C# 控制器中的后台工作程序是否异步?
在asp.net mvc 2控制器中,我有以下代码:C# 控制器中的后台工作程序是否异步?,c#,asp.net-mvc,asp.net-mvc-2,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);
using (BackgroundWorker worker = new BackgroundWorker())
{
worker.DoWork += new DoWorkEventHandler(blah);
worker.RunWorkerAsync(var);
}
我的问题是:这段代码是异步的,这意味着它启动一个新线程,控制器在并行执行“blah”时返回视图吗
如果没有,我将如何实现这些结果?我不确定这是否对您有效(我不是说不会,只是我不确定) 简短的回答是是,代码是异步的。但是,为了从
BackgroundWorker
获取任何类型的返回值,您需要处理其RunWorkerCompleted
事件
基本机制是将一些值放入DoWork
事件中的e.Result
属性中,然后从RunWorkerCompleted
事件中的e.Result
属性中检索它(确保首先检查e.Error
以查看DoWork
中是否引发异常)
我不确定它是否有效的原因是您正在使用
using
关键字,这确保BackgroundWorker
在代码块末尾被处理掉。由于它是异步执行其工作的,这可能会也可能不会阻止您有机会处理RunWorkerCompleted
。我真的不确定--也许其他人知道?我认为您可能会遇到问题,因为它会在后台线程仍在使用时尝试处理工作线程。如果没有别的,则会出现不可预测的行为。在MVC 2中,有一个新特性称为AsyncController,这是在MVC中进行异步调用的正确方法。您的控制器应继承自AsyncController,而不是控制器。然后,您的主操作方法名称的末尾应该有“Async”。例如,如果有一个名为Blah()的操作方法,则改为使用BlahAsync()命名,框架将自动识别该方法(并使用BlahCompleted()进行回调):
有关AsyncController的更多信息,请参见此处:
BackgroundWorker
不是您真正想要的:没有可通过回调更新的UI。您只需要将工作项激发到线程池线程,然后继续
ThreadPool.QueueUserWorkItem
方法可能更适合这里,或者使用新的任务并行方法:Task.Factory.StartNew(…)
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();
}