Ожидать или не ждать внутри метода Async AsyncController

Я видел 2 варианта работы с асинхронными операциями в контроллерах mvc.

Первый:

public void GetNewsAsync()
{
    AsyncManager.OutstandingOperations.Increment();
    using (ManualResetEvent mre = new ManualResetEvent(false))
    {
        //Perform the actual operation in a worker thread
        ThreadPool.QueueUserWorkItem((object _mre) =>
        {
            //do some work in GetFeed that takes a long time
            var feed = GetFeed();

            AsyncManager.Parameters["Feed"] = feed;
            AsyncManager.OutstandingOperations.Decrement();
            mre.Set();

        }, mre);

        //Wait for the worker thread to finish
        mre.WaitOne(TimeSpan.FromSeconds(SomeNumberOfSecondsToWait));
    }
}

Во-вторых:

public void GetNewsAsync()
{
    AsyncManager.OutstandingOperations.Increment();

    //Perform the actual operation in a worker thread
    ThreadPool.QueueUserWorkItem((object x) =>
    {
        //do some work in GetFeed that takes a long time
        var feed = GetFeed();

        AsyncManager.Parameters["Feed"] = feed;
        AsyncManager.OutstandingOperations.Decrement();

    }, null);
}

Первый блокирует GetNewsAsync для SomeNumberOfSecondsToWait, второй - нет. Оба выполняют работу внутри рабочего потока, а результаты передаются в GetNewsCompleted.

Поэтому мой вопрос в том, как правильно обрабатывать Ajax-вызов GetNews; Подождите или не ждите?

1 ответ

Я не знаю, где вы увидели первый пример, но это полный анти-паттерн, который полностью противоречит цели асинхронного контроллера. Весь смысл асинхронной операции состоит в том, чтобы выполнить асинхронно и максимально быстро освободить основной поток.

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

Таким образом, оба эти примера принесут больше накладных расходов, чем любая выгода.

Асинхронные контроллеры полезны, когда у вас есть какой-то интенсивный API ввода-вывода, например, вызов базы данных или веб-службы, где вы можете воспользоваться преимуществами портов завершения ввода-вывода. Следующая статья предоставляет хороший пример этого сценария. newsService Используется обеспечивает реальные асинхронные методы и нет блокировки во время сетевого вызова ввода-вывода. Никакой рабочий поток не подвергается опасности.

Я также рекомендую вам прочитать следующую статью. Даже если это классические веб-формы, они все же содержат очень полезную информацию.

Другие вопросы по тегам