异步方法中的警告消息说它缺少等待运算符

时间:2014-01-23 08:37:54

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

我在asp.net mvc 4应用程序中有一个excel下载。当我单击导出按钮时,将调用以下控制器方法。因为我需要它以异步方式完成,所以我在这里使用异步并等待。

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'运算符并将同步运行。   考虑使用'await'运算符来等待非阻塞API调用,   或'等待Task.Run(...)'在后台线程上进行CPU绑定工作

。我做错了什么?。我的代码工作正常,我能够下载excel。

1 个答案:

答案 0 :(得分:60)

  

我做错了吗?

嗯,你并没有真正做任何异步的事情。您的ReportExcelAsync方法完全同步,因为它没有任何await表达式。因此GenerateReportExcel将调用ReportExcelAsync,它将同步运行,然后返回已完成的任务。您目前所做的只是添加少量开销,用于创建用于实现async / await的状态机等。

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

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

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

然而,目前尚不清楚这实际上会给你带来多少好处。你正在编写一个网络应用程序,所以它不会像这样以更快的速度传递响应 - 你实际上只是转移工作完成的线程。

你说:

  

因为我需要它来完成异步

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