Я хочу, чтобы каждый получил равные шансы, как мне это сделать в C #? - PullRequest
1 голос
/ 18 апреля 2011

У меня есть такая функция,

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 #?

Большое спасибо за помощь !!!

Ответы [ 3 ]

4 голосов
/ 18 апреля 2011

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.");
    }
}

В вашем сценарии вы можете просто поставить в очередь все рабочие элементы из различных списков.Нет гарантии порядка обработки с пулом потоков.Однако, если выполняемая работа довольно «коротка», то есть, если время, необходимое для отправки потока, «примерно такое же, как» время, необходимое для выполнения фактической работы, тогда вы можете перетасовать действия так, чтобыобеспечить более справедливый шанс среди всех потоков пула потоков.

Если ваши действия выполняются в течение длительного времени - скажем, десятки секунд или более - тогда пул потоков обеспечит хорошую справедливость в любом случае, и при условии отсутствия конфликтов между потоками, вам, вероятно, не нужно будет перетасовывать рабочие элементы.прежде чем поставить их в очередь.

4 голосов
/ 18 апреля 2011

Я бы определил интерфейс IActable (выберите ваше имя), который определяет Act().

public interface IActable
{
  void Act();
}

Сделать A, B, и C реализовать IActable.Затем измените свою функцию, сделав следующее:

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();
    }
}

Метод случайного выбора, украденный отсюда

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());
    }
1 голос
/ 18 апреля 2011

Вы можете запустить их все параллельно, используя несколько потоков (ответ Cheeso) - обратите внимание, что нет абсолютно никаких гарантий, что в этом случае все методы будут работать одновременно. Вы должны определить, что на самом деле означает «равный шанс» в вашем случае, прежде чем переходить к многопоточному подходу.

Или вам нужно решить, в каком порядке вы хотите выполнить свою функцию, и сделать соответствующий порядок. То есть назначьте приоритеты, поместите все в один и тот же список (см. ответ Брука) и отсортируйте их по приоритетам.

...