Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 任务。运行isn';它不会像我想象的那样异步运行吗?_C#_Asynchronous_Async Await_Asp.net Mvc 5 - Fatal编程技术网

C# 任务。运行isn';它不会像我想象的那样异步运行吗?

C# 任务。运行isn';它不会像我想象的那样异步运行吗?,c#,asynchronous,async-await,asp.net-mvc-5,C#,Asynchronous,Async Await,Asp.net Mvc 5,我想在另一个线程上执行一个导入操作,希望UI立即响应。因此,我开始沿着这条路走,并创建了一个如下的动作: [HttpPost] public async Task<RedirectToRouteResult> ImportAsync(HttpPostedFileBase file) { var importsRoot = Server.MapPath("~/App_Data/Imports"); var path = Path.ChangeExtension(Path

我想在另一个线程上执行一个导入操作,希望UI立即响应。因此,我开始沿着这条路走,并创建了一个如下的动作:

[HttpPost]
public async Task<RedirectToRouteResult> ImportAsync(HttpPostedFileBase file)
{
    var importsRoot = Server.MapPath("~/App_Data/Imports");
    var path = Path.ChangeExtension(Path.Combine(importsRoot, Guid.NewGuid().ToString()), "txt");

    if (!Directory.Exists(importsRoot))
    {
        Directory.CreateDirectory(importsRoot);
    }

    file.SaveAs(path);

    // start the import process
    await ImportManager.Instance.StartImport(User.Identity.Name);

    return RedirectToAction("Index");
}
public async Task StartImport(string user)
{
    string[] files;

    var importRoot = HttpContext.Current.Server.MapPath("~/App_Data/Imports");
    var processingRoot = HttpContext.Current.Server.MapPath("~/App_Data/Processing");
    var processedRoot = HttpContext.Current.Server.MapPath("~/App_Data/Processed");

    lock (lockObj)
    {
        //  make sure the "Processing" folder exists
        if (!Directory.Exists(processingRoot))
        {
            Directory.CreateDirectory(processingRoot);
        }

        //  find all of the files available and move them to the "Processing" folder
        files = Directory.GetFiles(importRoot);
        foreach (var file in files)
        {
            var fileName = Path.GetFileName(file);
            if (fileName == null)
            {
                continue;
            }

            File.Move(file, Path.Combine(processingRoot, fileName));
        }

        //  make sure the "Processed" directory exists
        if (!Directory.Exists(processedRoot))
        {
            Directory.CreateDirectory(processedRoot);
        }
    }

    await Task.Run(() =>
    {
        //  start processing the files
        foreach (var file in files)
        {
            var fileName = Path.GetFileName(file);
            if (fileName == null)
            {
                continue;
            }

            var processingFileName = Path.Combine(processingRoot, fileName);
            var processedFileName = Path.Combine(processedRoot, fileName);

            var recognizer = new Recognizer(processingFileName);
            recognizer.ProgressChanged += (s, e) => Clients.All.updateImportStatus(e.ProgressPercentage, user);
            recognizer.Recognize(DataManager.GetExclusionPatterns());

            //  move the file to the "Processed" folder
            File.Move(processingFileName, processedFileName);
        }

        Clients.All.importComplete();
    });
}
发生了什么事? 调试我们发现,当我点击
wait Task.Run(()=>
时,它会同步运行(至少有一段时间),因为在读取了30K+行之前,UI不会收到重定向到
索引的请求


我怎样才能简单地执行并忘记它?我是否需要使用不同的方法?

它正在异步运行;但您正在等待它:

未等待;正在等待。
重定向到操作
现在是一个继续,将在其他代码完成时调用

如果您不想等待,请不要
等待
。但是,您应该考虑发生错误时会发生什么,等等。如果没有人注意到,请不要让
异步
方法引发异常:糟糕的事情

我怎样才能简单地执行并忘记它

我强烈建议你不要使用“开火然后忘记”在ASP.NET上。核心原因是ASP.NET围绕请求生命周期管理您的应用程序生命周期。因此,如果您执行的代码不是请求的一部分,则ASP.NET可能会关闭您的应用程序。在一般情况下,这意味着您不能依赖实际执行的代码

我需要使用不同的方法吗

正确的解决方案是将工作放入一个可靠的队列(例如Azure队列或MSMQ),并让一个独立的后端执行实际的处理(例如Azure webrole、Azure worker role或Win32 service)。这是相当多的工作,但这是唯一可靠的解决方案


但是,如果您想生活在危险之中,并将工作保存在ASP.NET进程的内存中,您应该在ASP.NET运行时注册该工作。您仍然不能保证该进程将执行,但更可能的是,因为ASP.NET知道您的代码。我有一个。

所以不要等待
StartImport
只要执行它,
RedirectToAction
将是即时响应?@MichaelPerrenoud不,它将在该点创建一个延续,在
wait
之后的代码将是该延续的一部分,并将在异步任务完成时执行。@MichaelPerrenoud确实如此;我添加了最后一行来解释这一点,但有一个重要的警告exceptions@MarcGravell,太好了!我擅长处理异常,因为我会在处理过程中默默地处理这些异常,然后手动处理它们。@AdamHouldsworth它只是一个延续,因为
wait
。如果OP删除
wait
,它就不再是一个延续。事实上,如果没有
await
操作也不需要是
async
方法。
await ImportManager.Instance.StartImport(User.Identity.Name);

return RedirectToAction("Index");