是控制器异步的后台工作者?

时间:2010-08-24 22:47:12

标签: c# asp.net-mvc asp.net-mvc-2

在asp.net mvc 2控制器中,我有以下代码:

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

我的问题是:这个代码是异步的,这意味着它会启动一个新线程,并且当'blah'并行执行时,控制器会返回视图吗?

如果没有,我将如何实现这些结果?

4 个答案:

答案 0 :(得分:7)

在MVC 2中有一个名为AsyncController的新功能,它是在MVC中进行异步调用的正确方法。您的控制器应该继承AsyncController而不是控制器。然后,您的主要操作方法名称应该在末尾具有“异步”。例如,如果你有一个名为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 :(得分:1)

BackgroundWorker并不是你想要的:没有用回调更新的UI。您只想将工作项启动到线程池线程并继续。

ThreadPool.QueueUserWorkItem方法可能更适合此处,或使用新的任务并行方法:Task.Factory.StartNew(...)

答案 2 :(得分:0)

我不确定这会对你有用(我不是说不会,只是因为我不是肯定)。

简短的回答是,代码是异步的。但是,为了从BackgroundWorker获得任何类型的返回值,您需要处理其RunWorkerCompleted事件。

基本机制是在e.Result事件的DoWork属性中添加一些值,然后从e.Result事件中的RunWorkerCompleted属性中检索它(确保首先检查e.Error以查看是否在DoWork中抛出了异常。

我不确定它是否会成功的原因是您使用的是using关键字,这可确保BackgroundWorker在代码块的末尾处理掉。由于它以异步方式执行其工作,这可能会或可能不会阻止您有机会处理RunWorkerCompleted。我真的不确定 - 也许其他人都知道?

答案 3 :(得分:0)

我认为您可能会遇到问题,因为它会在后台线程仍在使用时尝试处理该工作线程。如果没有别的,不可预测的行为。