Вопрос по c#, multithreading – Разница между делегатом. BeginInvoke и использованием потоков ThreadPool в C #

29

В C # есть ли разница между использованием делегата для асинхронного выполнения некоторой работы (вызов BeginInvoke ()) и использованием потока ThreadPool, как показано ниже

public void asynchronousWork(object num)
    {
        //asynchronous work to be done
        Console.WriteLine(num);
    }

 public void test()
    {
        Action<object> myCustomDelegate = this.asynchronousWork;
        int x = 7;

        //Using Delegate
        myCustomDelegate.BeginInvoke(7, null, null);

        //Using Threadpool
        ThreadPool.QueueUserWorkItem(new WaitCallback(asynchronousWork), 7);
        Thread.Sleep(2000);
    }

Edit:
BeginInvoke гарантирует, что поток из пула потоков используется для выполнения асинхронного кода, так есть ли разница?

Я не уверен, был ли ваш комментарий до того, как я отредактировал мой вопрос, но я знаю, что BeginInvoke выполняет делегаты в потоках, принадлежащих пулу потоков. Мой вопрос был больше о том, есть ли какая-либо разница между явным выполнением метода в пуле потоков с использованием QueueUserWorkItem или с помощью BeginInvoke nighthawk457
возможный дубликатDoes Func<T>.BeginInvoke use the ThreadPool? nothrow

Ваш Ответ

1   ответ
32

Concurrent Programming on Windows книга (стр. 418), говорит об этомDelegate.BeginInvoke:

All delegate types, by convention offer a BeginInvoke and EndInvoke method alongside the ordinary synchronous Invoke method. While this is a nice programming model feature, you should stay away from them wherever possible. The implementation uses remoting infrastructure which imposes a sizable overhead to asynchronous invocation. Queue work to the thread pool directly is often a better approach, though that means you have to co-ordinate the rendezvous logic yourself.

РЕДАКТИРОВАТЬ: я создал следующий простой тест относительных накладных расходов:

int counter = 0;
int iterations = 1000000;
Action d = () => { Interlocked.Increment(ref counter); };

var stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
for (int i = 0; i < iterations; i++)
{
    var asyncResult = d.BeginInvoke(null, null);
}

do { } while(counter < iterations);
stopwatch.Stop();

Console.WriteLine("Took {0}ms", stopwatch.ElapsedMilliseconds);
Console.ReadLine();

На моей машине вышеуказанный тест выполняется примерно за 20 секунд. ЗаменаBeginInvoke позвонить с

System.Threading.ThreadPool.QueueUserWorkItem(state =>
{
    Interlocked.Increment(ref counter);
});

изменяет время работы до 864мс.

Error: User Rate Limit ExceededBeginInvokeError: User Rate Limit ExceededBeginInvokeError: User Rate Limit ExceededBindError: User Rate Limit ExceededMethodInvoker.
Error: User Rate Limit Exceededa sizable overhead to asynchronous invocation.Error: User Rate Limit Exceededto co-ordinate the rendezvous logic yourself...Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededTaskError: User Rate Limit ExceededIAsyncResultError: User Rate Limit Exceeded
Error: User Rate Limit ExceededAction.BeginInvoke(...)Error: User Rate Limit ExceededThreadPoolError: User Rate Limit ExceededTask.Start()Error: User Rate Limit ExceededInterlocked.Increment(ref counter)Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededDelegate.Begin\EndInvokeError: User Rate Limit ExceededBeginInvoke\EndInvokeError: User Rate Limit ExceededIAsyncResultError: User Rate Limit ExceededTaskError: User Rate Limit Exceeded

Похожие вопросы