在asp.net mvc 2控制器中,我有以下代码:
using (BackgroundWorker worker = new BackgroundWorker())
{
worker.DoWork += new DoWorkEventHandler(blah);
worker.RunWorkerAsync(var);
}
我的问题是:这个代码是异步的,这意味着它会启动一个新线程,并且当'blah'并行执行时,控制器会返回视图吗?
如果没有,我将如何实现这些结果?
答案 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)
我认为您可能会遇到问题,因为它会在后台线程仍在使用时尝试处理该工作线程。如果没有别的,不可预测的行为。