фоновый рабочий в контроллере асинхронен? - PullRequest
5 голосов
/ 25 августа 2010

Внутри контроллера asp.net mvc 2 у меня есть следующий код:

using (BackgroundWorker worker = new BackgroundWorker())
                        {
                            worker.DoWork += new DoWorkEventHandler(blah);
                            worker.RunWorkerAsync(var);
                        }

Мой вопрос: является ли этот код асинхронным, что означает, что он запускает новый поток, а контроллер возвращает представление, пока «бла» выполняется параллельно?

Если нет, как бы я достиг этих результатов?

Ответы [ 4 ]

7 голосов
/ 25 августа 2010

В MVC 2 есть новая функция, называемая AsyncController, которая является правильным способом выполнения асинхронных вызовов в MVC.Ваш контроллер должен наследовать от AsyncController, а не контроллера.Тогда у вас имя вашего основного метода действия должно иметь "Async" в конце.например, если у вас есть метод действия с именем Blah (), вы вместо этого назовете его в BlahAsync (), и это будет автоматически распознано платформой (и для ответа будет использоваться BlahCompleted ()):

public virtual void BlahAsync()
{
    AsyncManager.OutstandingOperations.Increment();
    var service = new SomeWebService();
    service.GetBlahCompleted += (sender, e) =>
        {
            AsyncManager.Parameters["blahs"] = e.Result;
            AsyncManager.OutstandingOperations.Decrement();
        };
    service.GetBlahAsync();
}

public virtual ActionResult BlahCompleted(Blah[] blahs)
{
    this.ViewData.Model = blahs;
    return this.View();
}

Больше информации об AsyncController здесь: MVC AsyncController

1 голос
/ 25 августа 2010

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

Метод ThreadPool.QueueUserWorkItem, вероятно, лучше подходит здесь, или используйте новый параллельный подход Task: Task.Factory.StartNew(...).

0 голосов
/ 25 августа 2010

Я думаю, что вы, вероятно, столкнетесь с проблемами, поскольку он попытается избавиться от работника, пока фоновый поток все еще используется.Если ничего другого, непредсказуемое поведение.

0 голосов
/ 25 августа 2010

Я не уверен, что это сработает для вас (я не говорю, что не , просто я не уверен ).

Краткий ответ: да , код асинхронный. Но чтобы получить любой тип возвращаемого значения из BackgroundWorker, вам нужно обработать его RunWorkerCompleted событие.

Основной механизм заключается в том, чтобы ввести какое-либо значение в свойство e.Result в вашем событии DoWork, а затем извлечь его из свойства e.Result в вашем событии RunWorkerCompleted (обязательно сначала отметив e.Error чтобы увидеть, было ли выброшено исключение в DoWork).

Причина, по которой я не уверен, сработает ли это, заключается в том, что вы используете ключевое слово using, которое обеспечивает удаление BackgroundWorker в конце блока кода. Поскольку он выполняет свою работу асинхронно, это может или не может помешать вам когда-либо получить возможность обрабатывать RunWorkerCompleted. Я действительно не уверен - может, кто-то еще знает?

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