【问题标题】:Warning message in async method saying that it lacks await operators异步方法中的警告消息说它缺少等待运算符
【发布时间】:2014-02-13 16:53:06
【问题描述】:

我在我的 asp.net mvc 4 应用程序中有一个 excel 下载。当我单击导出按钮时,将调用以下控制器方法。由于我需要异步完成,所以我在这里使用 async 和 await。

public async Task<ActionResult> GenerateReportExcel()
    {
        ExcelGenerator excel = new ExcelGenerator();
        var filePath = await excel.ReportExcelAsync(midyearReportViewModel);
        System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
        response.ClearContent();
        response.Clear();
        response.ContentType = "text/plain";
        response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}.xlsx;", PdaResource.ReportFileName)); 
        response.TransmitFile(filePath);
        response.Flush();
        response.End();
        return PartialView("_MidYearReportPartial", midyearReportViewModel);
    }

这个方法又调用一个excel生成器方法ReportExcelAsync,如下所示

public async Task<string> ReportExcelAsync(MidYearReportViewModel _midyearAnnualviewModel)
    {
        string fileName = "MidYearReport";
        string finalXcelPath = string.Empty;
        string currentDirectorypath = new DirectoryInfo(HttpContext.Current.Server.MapPath("~/Export")).ToString();
        finalXcelPath = string.Format("{0}\\{1}.xlsx", currentDirectorypath, fileName);
        if (System.IO.File.Exists(finalXcelPath))
        {
            System.IO.File.Delete(finalXcelPath);
        }
        var newFile = new FileInfo(finalXcelPath);
        using (ResXResourceSet resxSet = new ResXResourceSet(resxFile))
        {
            using (var package = new ExcelPackage(newFile))
            {
                ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(resxSet.GetString("ReportMYMidYearExcelSheetName"));
                for (int i = 1; i <= header.Count(); i++)
                {
                    worksheet.Cells[1, i].Value = header[i - 1];
                    worksheet.Cells[1, i].Style.Font.Bold = true;
                    worksheet.Cells[1, i].Style.Fill.PatternType = ExcelFillStyle.Solid;
                    worksheet.Cells[1, i].Style.Font.Color.SetColor(Color.White);
                    worksheet.Cells[1, i].Style.Fill.BackgroundColor.SetColor(Color.DimGray);
                }
                package.Save();
            }
        }
        return finalXcelPath; 
    }

但我收到警告消息作为警告

此异步方法缺少“等待”运算符,将同步运行。 考虑使用 'await' 运算符来等待非阻塞 API 调用, 或 'await Task.Run(...)' 在后台线程上执行 CPU 密集型工作

。我做错了什么吗?我的代码工作正常,我可以下载excel。

【问题讨论】:

    标签: c# asp.net-mvc-4 async-await


    【解决方案1】:

    我做错了吗?

    好吧,您实际上并没有异步执行任何操作。您的 ReportExcelAsync 方法是完全同步的,因为它没有任何 await 表达式。所以GenerateReportExcel会调用ReportExcelAsync,它会同步运行,然后返回一个完成的任务。您目前所做的只是添加少量开销来创建用于实现async/await 的状态机等。

    不清楚您为什么期望它实际上异步发生,但我怀疑这是对 await/async 实际作用的误解。它不会自动为您启动新线程 - 它只是让创建和使用异步 API 变得更加容易。

    现在一种选择是将ReportExcelAsync 更改为同步方法(ReportExcel,返回string)并在调用代码中为此创建一个新任务:

    var filePath = await Task.Run(excel.ReportExcel);
    

    但是,尚不清楚这实际上会给您带来多少好处。您正在编写一个 Web 应用程序,因此通过这种方式并不会更快地传递响应 - 您实际上只是在转移完成工作的线程。

    你说:

    因为我需要异步完成

    ...但没有说明为什么它需要异步完成。在这种情况下,同步方法有什么问题?异步在适当的时候很棒,但我不认为它适合你。

    【讨论】:

    • 这行不是什么 var filePath = await excel.ReportExcelAsync(midyearReportViewModel);是在做?第二行。
    • @stevethethread:那将是异步执行的操作如果 ReportExcelAsync 确实是异步的 - 但事实并非如此。这是生成警告的方法,因为它没有 await 表达式。
    • @user2988112:我怀疑您对“异步”一词的理解与我的不同。你所做的一切都是同步的——你期望异步在哪里出现,你期望它有什么具体的好处?您实际上想在这里解决什么问题
    • @user2988112:为什么?你还有很多工作要做,而且都是在本地完成的。这不像你会释放任何线程。感觉就像您将异步视为灵丹妙药-实际上并非如此。您必须考虑实际的异步从何而来。例如,如果您可以从数据库中异步获取数据,或者执行可以减少所需线程数量的异步 IO - 但否则我认为它不会对您有所帮助。您目前真的性能问题吗?
    • @Skeet 不是。目前可能有 30-40 个用户,最多可能会上升到 200-300 个。感谢您的澄清。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    • 2017-04-30
    • 1970-01-01
    • 2019-08-27
    • 2021-01-24
    • 2017-11-09
    • 2019-09-25
    相关资源
    最近更新 更多