在异步方法的警告消息说,它缺乏等待运营商 [英] Warning message in async method saying that it lacks await operators

查看:202
本文介绍了在异步方法的警告消息说,它缺乏等待运营商的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的asp.net mvc的4应用一个excel下载。当我点击导出按钮下面的控制器方法被调用。因为我需要它做异步,我使用异步这里等待着。

 公共异步任务<&的ActionResult GT; GenerateReportExcel()
    {
        ExcelGenerator的Excel =新ExcelGenerator();
        VAR文件路径=等待excel.ReportExcelAsync(midyearReportViewModel);
        System.Web.Htt presponse响应= System.Web.HttpContext.Current.Response;
        response.ClearContent();
        response.Clear();
        response.ContentType =text / plain的;
        response.AddHeader(内容处置的String.Format(附件;文件名= {0}的.xlsx;,PdaResource.ReportFileName));
        response.TransmitFile(文件路径);
        response.Flush();
        到Response.End();
        返回PartialView(_ MidYearReportPartial,midyearReportViewModel);
    }

这个方法调用inturn一个excel发生器方法ReportExcelAsync如下图所示。

 公共异步任务<串GT; ReportExcelAsync(MidYearReportViewModel _midyearAnnualviewModel)
    {
        字符串文件名=MidYearReport;
        字符串finalXcelPath =的String.Empty;
        字符串currentDirectorypath =新的DirectoryInfo(HttpContext.Current.Server.MapPath(〜/导出))的ToString()。
        finalXcelPath =的String.Format({0} \\\\ {1}的.xlsx,currentDirectorypath,文件名);
        如果(System.IO.File.Exists(finalXcelPath))
        {
            System.IO.File.Delete(finalXcelPath);
        }
        VAR NEWFILE =新的FileInfo(finalXcelPath);
        使用(ResXResourceSet resxSet =新ResXResourceSet(resxFile))
        {
            使用(VAR包=新ExcelPackage(NEWFILE))
            {
                ExcelWorksheet工作表= package.Workbook.Worksheets.Add(resxSet.GetString(ReportMYMidYearExcelSheetName));
                的for(int i = 1; I< = header.Count();我++)
                {
                    worksheet.Cells [1,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();
            }
        }
        返回finalXcelPath;
    }

不过,我得到一个警告消息作为警告


  

这异步方法缺乏'等待'经营者和将同步运行。
  考虑使用'等待'操作等待非阻塞-API调用,
  或等待Task.Run(...)做在后台线程CPU密集型的工作


。难道我做错了什么?。我的code正常工作,我能够得到的Excel下载。


解决方案

  

我是不是做错了什么?


好吧,你没有真正做任何事情异步。你的 ReportExcelAsync 方法是完全同步的,因为它没有任何的await 前pressions。因此, GenerateReportExcel 将调用 ReportExcelAsync ,这将同步运行,然后返回一个完成的任务。所有你此刻做的是增加开销少量用于创建状态机等用于实施异步 / 的await

目前还不清楚为什么你期望它实际上是同步发生的,但我怀疑这是什么等待/异步实际上做了误解。它的的自动启动新的线程你 - 它只是使你更容易创建和使用异步API的

现在一种选择是只需要换 ReportExcelAsync 成一个同步方法( ReportExcel ,返回字符串),并创建一个新的任务,在调用code:

  VAR文件路径=等待Task.Run(excel.ReportExcel);

不过,目前还不清楚,这实际上给你多少好处。你写一个web应用程序,所以它不喜欢的反应是怎么回事任何这种方式更快地交付 - 你有效地只是的线程的工作是上完成

您说的:


  

因为我需要它做异步


...但不提供任何理由的为什么的它需要异步完成。这有什么错在这种情况下同步的方法呢?异步是伟大的,当它是适当的,但我不认为这是你的情况。

I have a excel download in my asp.net mvc 4 application. When I click the export button the below controller method gets called. Since I need it to be done asynchronous, I am using async and await here.

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

This method inturn call a excel generator method ReportExcelAsync as shown below

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

But I get a warning message as Warning

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread

. Am I doing something wrong ?.My code works fine and I am able to get the excel downloaded.

解决方案

Am I doing something wrong?

Well, you're not really doing anything asynchronously. Your ReportExcelAsync method is entirely synchronous, as it doesn't have any await expressions. So GenerateReportExcel will call ReportExcelAsync, which will run synchronously, and then return a completed task. All you've done at the moment is add a small amount of overhead for creating the state machine etc that is used to implement async/await.

It's not clear why you expected it to actually happen asynchronously, but I suspect it's a misunderstanding of what await/async actually does. It doesn't start up new threads for you automatically - it just makes it much easier to create and consume asynchronous APIs.

Now one option is to just want to change ReportExcelAsync into a synchronous method (ReportExcel, returning a string) and create a new task for that in the calling code:

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

However, it's not clear that this would actually give you much benefit. You're writing a web app, so it's not like the response is going to be delivered any faster this way - you're effectively just shifting the thread the work is done on.

You say:

Since I need it to be done asynchronous

... but give no reasons why it needs to be done asynchronously. What's wrong with the synchronous approach in this case? Asynchrony is great when it's appropriate, but I don't think it is in your case.

这篇关于在异步方法的警告消息说,它缺乏等待运营商的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆