如何将控制器操作转换为非阻塞/异步

本文关键字:异步 转换 控制器 操作 | 更新日期: 2023-09-27 18:33:59

我有一个控制器操作,它接受一个文件,解析该文件并从中导入数据,然后返回一个文件:

    public FileResult ImportDevices()
    {
        HttpPostedFileBase csvFile = Request.Files[0] as HttpPostedFileBase;
        if (csvFile != null || csvFile.ContentLength != 0)
        {
            SaveDevicesResult result = CADC.SaveCSVDeviceData(csvFile.InputStream);
            string csvString = result.ToString();
            UTF8Encoding encoding = new UTF8Encoding();
            byte[] bytes = encoding.GetBytes(csvString);
            return File(bytes, "text/txt", "ImportResults.txt");
        }
        return null; // Not sure how to handle this case, that's another question though!
    }

我希望这是非阻塞的,因为导入可能需要一段时间。我希望用户能够浏览页面,并在准备好时将文件作为下载返回。

我是否遵循这个:http://msdn.microsoft.com/en-us/library/ee728598%28v=vs.100%29.aspx

还是我使用异步和等待?

还是它们是一回事,我很困惑?

如何将控制器操作转换为非阻塞/异步

您需要编写一个异步控制器方法来处理此问题,并且还必须重写 SaveCSVDeviceData 方法以返回Task<SaveDevicesResult>。您在此处尝试执行的操作是通过 async/await 模式完成的,这可以通过以下方式实现

public async Task<ActionResult> ImportDevicesAsync()
{
    var csvFile = Request.Files[0] as HttpPostedFileBase;
    if(csvFile != null && csvFile.ContentLength != 0)
    {
        // Note: I would recommend you do not do this here but in a helper class
        // for this to work, SaveCSVDeviceDataAsync *must* return a Task<object>()
        var result = await CADC.SaveCSVDeviceDataAsync(csvFile.InputStream);
        var csvString = result.ToString();
        var encoding = new UTF8Encoding();
        var bytes = encoding.GetBytes(csvString);
        // if you are returning a csv, return MIME type text/csv
        return File(bytes, "text/txt", "ImportResults.txt");
    }
    // If the file is null / empty, then you should return
    // a validation error
    return Error(500, ...);
}

正如我所提到的,为了使它正常工作,您的CADC.SaveCsvDeviceData必须返回一个Task<SaveDevicesResult>。鉴于您正在传递该方法InputStream我将提醒您,InputStream上的所有方法在 .NET 4.5 + 中都有一个可等待的替代方案。

它们不是一回事,您发布的链接与 MVC 1.0 有关,这是一种古老的方法。对于 MVC 4,请参阅在 MVC 4 中使用异步方法 ASP.NET。