MVC5如何使用异步来执行渐进任务



我有个需求。我有一个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
}

最新更新