我有个需求。我有一个MVC5网站。我使用的是普通的控制器模型结构。我从Javascript中执行一个控制器函数。我必须处理一些上传的xml文件。当控制器第一次执行这个函数时,直到处理完所有的xml文件,它才返回到浏览器。
这就是我想要的。我想执行控制器函数来执行模型方法。在该方法中,我想选择所有xml文件,然后我想异步处理它们。下面是代码:
var raw = new DirectoryInfo(xconfig.Directory.FullName + "//raw");
if (raw.Exists)
{
var xmls = raw.GetFiles("*.xml");
foreach (var xml in xmls)
{
if(ProcessedXmlFiles != null)
{
if(!ProcessedXmlFiles.Contains(xml.Name))
{
ExportData(xml);
ProcessedXmlFiles.Add(xml.Name);
}
}
}
}
当上面的代码执行时,我调用另一个javascript方法来获取使用普通ajax调用处理了多少文件的更新。我调用另一个控制器方法返回ProcessedXmlFiles。计算一下,知道到目前为止已经处理了多少个!
您可以简单地使您的操作返回Task
并将您的进程置于Task.Run中。
public async Task<ActionResult> MyAction(object param)
{
var raw = new DirectoryInfo(xconfig.Directory.FullName + "//raw");
if (raw.Exists)
{
await Task.Run(() =>
{
var xmls = raw.GetFiles("*.xml");
foreach (var xml in xmls)
{
if(ProcessedXmlFiles != null)
{
if(!ProcessedXmlFiles.Contains(xml.Name))
{
ExportData(xml);
ProcessedXmlFiles.Add(xml.Name);
}
}
}
});
// Do something
}
return View();
}
编辑:因为OP似乎期望不同的行为比异步编程所能提供的,我建议使用后台工作者代替,但请注意,在web应用程序中使用后台工作者是不可取的。ASP。. NET以请求-响应的方式工作。我建议让用户等待进程结束后再呈现视图。
public ActionResult MyAction(object param)
{
ExecuteBackgroundWorker(param); // your model containing the method you want to execute
return View(); // This will return the view while the background worker proceeds.
}
public void ExecuteBackgroundWorker(object param)
{
BackgroundWorker bgWorker = new BackgroundWorker();
bgWorker.DoWork += bgWorker_DoWork;
bgWorker.RunWorkerCompleted += bgWorker_RunWorkerCompleted;
bgWorker.RunWorkerAsync(param);
}
void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Do Something when work ends
}
void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
var OPsModel = (MyModel)e.Argument; // Cast object back to original model
OPsModel.ExecuteProcess(); // Execute the process
}