Ожидать или не ждать внутри метода Async AsyncController - PullRequest
0 голосов
/ 22 ноября 2011

Я видел 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 второй нет.Оба выполняют работу внутри a рабочего потока, а результаты передаются в GetNewsCompleted.

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

1 Ответ

2 голосов
/ 22 ноября 2011

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

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

Таким образом, оба этих примера принесут больше издержек, чем какое-либо преимущество.

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

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

...