Параллельные (асинхронные) задачи с использованием веб-службы, чтобы избежать потоков - PullRequest
2 голосов
/ 17 июня 2011

У меня есть задача, которую я выполняю параллельно; например, печать выбранных пользователем документов асинхронно. Одним из способов может быть использование рабочего потока. Но думать о сценарии, когда тысячи запросов вливаются на веб-сервер, а приложение создает еще один поток для печати, звучит ужасно. А что, если все одновременные пользователи начнут печатать?

Так вот почему я хочу избегать рабочих потоков.

Чтобы обойти это, я переместил код в веб-сервис; Я вызываю метод PrintAsync() и подписался на OnPrintComplete, чтобы получать уведомления. Теперь я могу отправлять столько распечаток, сколько захочу, не беспокоясь о нехватке потоков asp.net и не блокируя запросы.

Я знаю, что веб-службы внутренне используют потоки, но это потоки IOCP, что означает, что они не будут мешать рабочим потокам asp.net.

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

Это хороший подход? Какой была бы лучше альтернатива версия обработки этой функциональности?

Ответы [ 2 ]

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

Итак, вы описали, как вы делаете асинхронные вызовы на клиенте, и на самом деле есть еще несколько вопросов, которые я хотел бы задать о том, как вы на самом деле полностью асинхронны, но, похоже, ваш вопрос больше о том, как быть максимально эффективно на стороне обслуживания, верно?

Если вы выполняете длительные или связанные с вводом / выводом операции в своих сервисных операциях, вы абсолютно должны начать использовать поддержку WCF для асинхронных сервисных операций . Теперь есть много способов сделать это, но если вы используете .NET 4.0, нет лучшего способа, чем использовать Task Parallel Library (TPL).

Во-первых, выгружая работу в поток TPL, вы освобождаете потоки ввода / вывода WCF для обработки большего количества вызовов. Таким образом, ваши длительные операции WCF не связывают способность WCF выставлять другие операции.

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

В-третьих, TPL можно комбинировать с традиционной моделью асинхронного программирования (APM) , так что если вы работаете с такими вещами, как Streams (сеть или файл), вы можете использовать их BeginRead/Write методы максимально использовать асинхронный ввод / вывод, который освободит потоки процессора при блокировке чтения / записи. Вы должны делать это, чтобы достичь максимальной эффективности, даже если вы не используете TPL, TPL просто делает это проще.

Вот простой пример того, как вы можете использовать TPL для реализации асинхронной операции службы:

public IAsyncResult BeginSomeLongRunningOperation(string sampleParam, AsyncCallback callback, object asyncState)
{
    Task<int> processingTask = Task<int>.Factory.StartNew(
        _ =>
        {
             ... perform insanely long running operation here ...

             return 42;    
        },
        asyncState);

    // If there was a callback, we have to invoke it after the processing finishes
    if(callback != null)
    {
        processingTask.ContinueWith(
            _ =>
            {
                callback(calculationTask);                   
            },
            TaskContinuationOptions.ExecuteSynchronously);
    }

    return processingTask;
}

public int EndSomeLongRunningOperation(IAsyncResult asyncResult)
{
    return ((Task<int>)asyncResult).Result;
}
1 голос
/ 17 июня 2011

как насчет очереди сообщений Microsoft (MSMQ)?

С помощью этой архитектуры вы можете поставить в очередь все запросы на печать, а затем использовать службу Windows для получения и обработки после другого.

Это довольно легко настроить и поддерживает распределенные транзакции.

MSMQ на MSDN

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...