简体   繁体   English

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

[英]MVC5 how to use async to perform a progressive task?

I have a need.我有需要。 I have an MVC5 website.我有一个 MVC5 网站。 i am using normal contorller-model structure.我正在使用正常的控制器模型结构。 Where I execute a controller function from Javascript.我从 Javascript 执行控制器功能的地方。 I have to process some xml files as they are uploaded.我必须在上传时处理一些 xml 文件。 What happens when the controller executes the function for the first time it doesnt come back to the browser until all the xml files are processed.当控制器第一次执行函数时会发生什么,直到所有的 xml 文件都被处理完才返回到浏览器。

So here is what i want.所以这就是我想要的。 I want to execute controller function to execute model method.我想执行控制器功能来执行模型方法。 In that method i want pick all xml files and then i want asynchronously process them.在那种方法中,我想选择所有 xml 文件,然后我想异步处理它们。 here is the code:这是代码:

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);
            }
        }
    }
}

When the above code is executing, I call another javascript method to get the updates how many files have been processed using normal ajax call.当上面的代码执行时,我调用另一个 javascript 方法来获取使用普通 ajax 调用处理了多少文件的更新。 So I just call another contrller method where I return the ProcessedXmlFiles.Count to know how many of them have been processed so far!所以我只是调用另一个控制器方法,在那里我返回 ProcessedXmlFiles.Count 以了解到目前为止已经处理了多少!

You can simply make your action return a Task and place your process inside a Task.Run .您可以简单地让您的操作返回一个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();
}

EDIT: Since OP seems to be expecting a different behavior than what asynchronous programming can offer, I suggest using a background worker instead but take note that using background workers in web apps is not desirable.编辑:由于 OP 似乎期望与异步编程可以提供的行为不同,我建议改用后台工作人员,但请注意,在 Web 应用程序中使用后台工作人员是不可取的。 ASP.NET works in a request-response manner. ASP.NET 以请求-响应方式工作。 I suggest letting the user wait for the process to end before rendering the view.我建议让用户在渲染视图之前等待进程结束。

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM