我想要一种方式,让每个人都有平等的机会,我如何在c#中做到这一点



我有一个函数,像这样,

private void Step()
{
    foreach (A a in aList)
        a.Act();
    foreach (B b in bList)
        b.Act();
    foreach (C c in cList)
        c.Act();
}

a获得第一个机会b获得第二个机会c获得最后一个机会,

我想要一种方法,让每个人都有平等的机会,我怎么在c#中做到这一点?

谢谢你的帮助!

我将定义一个接口IActable(选择您的名字),它定义Act()

public interface IActable
{
  void Act();
}

使A、B和C实现可执行性。然后,将函数更改为以下操作:

private void Step()
{
    var all = new List<IActable>();
    all.AddRange(aList);
    all.AddRange(bList);
    all.AddRange(cList);
    all = all.Shuffle(new Random());
    foreach (IActable a in all)
    {
        a.Act();
    }
}

Shuffle方法,从这里偷来的

public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
{
    T[] elements = source.ToArray();
    // Note i > 0 to avoid final pointless iteration
    for (int i = elements.Length-1; i > 0; i--)
    {
        // Swap element "i" with a random earlier element it (or itself)
        int swapIndex = rng.Next(i + 1);
        T tmp = elements[i];
        elements[i] = elements[swapIndex];
        elements[swapIndex] = tmp;
    }
    // Lazily yield (avoiding aliasing issues etc)
    foreach (T element in elements)
    {
        yield return element;
    }
}

使用plinq的并行实现。(不保留顺序)

private void Step()
    {
        var all = new List<IActable>();
        all.AddRange(aList);
        all.AddRange(bList);
        all.AddRange(cList);
        all.AsParallel().ForAll(a=>a.Act());
    }

ThreadPool。QueueUserWorkItem

文档页中的示例:

using System;
using System.Threading;
public class Example {
    public static void Main() {
        // Queue the task.
        ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));
        Console.WriteLine("Main thread does some work, then sleeps.");
        // If you comment out the Sleep, the main thread exits, and
        // therefore the application ends, before the work item 
        // runs on the thread pool thread.  The thread pool uses background
        // threads, which do not keep the application running.  (This
        // is a simple example of a race condition.)
        Thread.Sleep(1000);
        Console.WriteLine("Main thread exits.");
    }
    // This method performs the work. It will be invoked in a thread
    // running in the .NET threadpool.
    static void ThreadProc(Object stateInfo) {
        // No state object was passed to QueueUserWorkItem, so 
        // stateInfo is null.
        Console.WriteLine("Hello from the thread pool.");
    }
}

在您的场景中,您可以简单地将来自各种列表的所有工作项排队。不能保证线程池的处理顺序。但是,如果要完成的工作相当"短"——也就是说,如果线程调度所需的时间与执行实际工作所需的时间"大致相同"——那么您可能希望对操作进行洗牌,以便在所有线程池线程之间提供更公平的机会。

如果您的操作运行时间较长——假设几十秒或更长——那么线程池将提供良好的公平性,并且假设线程之间没有争用,您可能不需要在对工作项进行排队之前对其进行洗刷。

您可以使用多个线程并行运行它们(Cheeso的答案)-注意,在这种情况下,绝对不能保证所有方法都将同时运行。在使用多线程方法之前,您应该定义"机会均等"的实际含义。

或者您需要决定您希望函数执行的顺序并进行适当的排序。即分配优先级,把所有的放在同一个列表中(参见Brook的回答),并按优先级排序。

相关内容

  • 没有找到相关文章

最新更新