Не найти способа сделать асинхронный вызов параллельно (многопоточность) - PullRequest
0 голосов
/ 17 июня 2011

Сначала у меня есть пример ожидания потока, и он отлично работает. Его задача - попросить 100 потоков подождать 3 секунды и затем сделать вывод:

for (int i = 0; i < 100; ++i)
{
    int index = i;
    Thread t = new Thread(() =>
        {
            Caller c = new Caller();
            c.DoWaitCall();
        }) { IsBackground = true };
    t.Start();
}

Звонящий :: DoWaitCall () выглядит так:

public void DoWaitCall()
{
    Thread.Sleep(3000);
    Console.WriteLine("done");
}

В этом случае все потоки ждут 3 секунды и выдают выводимое сообщение почти одновременно.

Но когда я пытаюсь использовать асинхронный обратный вызов для создания Console.WriteLine:

    public void DoWaitCall()
    {
        MyDel del = () => { Thread.Sleep(3000); };
        del.BeginInvoke(CallBack, del);
    }

    private void CallBack(IAsyncResult r)
    {
        Console.WriteLine("done");
    }

Каждый поток ожидает различное время и медленно выводит их один за другим. Есть ли хороший способ для параллельного асинхронного обратного вызова?

Ответы [ 2 ]

2 голосов
/ 17 июня 2011

Эффект, который вы видите, ThreadPool постепенно увеличивается, в основном.Идея заключается в том, что создание (а затем и сохранение) потоков относительно дорого, а ThreadPool предназначен для краткосрочных задач.Поэтому, если он получает кучу задач за короткий промежуток времени, имеет смысл их группировать, запускать новые потоки только тогда, когда он обнаруживает, что есть еще задачи, ожидающие чуть позже.

Вы можете принудительночтобы сохранить минимальное количество потоков, используя ThreadPool.SetMinThreads.Для реальных систем вам обычно не нужно этого делать, но это имеет смысл для демонстрации или чего-то подобного.

1 голос
/ 17 июня 2011

В первый раз вы создали много потоков, которые выполняют работу параллельно.Во второй раз вы использовали пул потоков, который имеет ограниченное количество потоков.Как отметил Джон, вы можете использовать свойство для определения минимального номера потока.

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

...