Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Warning message in async method saying that it lacks await operators

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.

like image 624
Jayason Avatar asked Jan 23 '14 08:01

Jayason


People also ask

What happens if you do not await an async method?

The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.

Can you call an async method without await?

You can call this method with or without the await keyword. The syntax with the await keyword looks like this: Customer cust = await GetCustomerById("A123");

What happens when you call async method without await C#?

However, just to address "Call an async method in C# without await", you can execute the async method inside a Task. Run . This approach will wait until MyAsyncMethod finish. await asynchronously unwraps the Result of your task, whereas just using Result would block until the task had completed.

What is await in async?

The await operator is used to wait for a Promise . It can only be used inside an async function within regular JavaScript code; however it can be used on its own with JavaScript modules.


1 Answers

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.

like image 148
Jon Skeet Avatar answered Sep 22 '22 22:09

Jon Skeet