2014-01-23 2 views
27

Ich habe einen Excel-Download in meiner asp.net mvc 4-Anwendung. Wenn ich auf die Export-Schaltfläche klicke, wird die folgende Controller-Methode aufgerufen. Da ich es asynchron machen muss, benutze ich async und erwarte hier.Warnmeldung in async-Methode, die sagt, dass es fehlt warten Bediener

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

Diese Methode inturn eine Excel-Generator Methode ReportExcelAsync nennen wie Warnung fehlt 'erwarten' Betreiber

Methode Diese async unter

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

Aber ich erhalte eine Warnmeldung angezeigt und wird synchron laufen. Betrachten wir die 'erwarten' Bedienungsperson warten nicht blockierende API-Aufrufe, oder 'await Task.Run (...)' CPU-gebundene Arbeit auf einem Hintergrund-Thread

zu tun. Mache ich etwas falsches? Mein Code funktioniert gut und ich kann das Excel herunterladen.

Antwort

58

Mache ich etwas falsch?

Nun, Sie tun nichts wirklich asynchron. Ihre ReportExcelAsync Methode ist vollständig synchron, da sie keine await Ausdrücke hat. So wird GenerateReportExcelReportExcelAsync aufrufen, die synchron ausgeführt wird, und dann eine abgeschlossene Aufgabe zurückgeben. Alles, was Sie im Moment getan haben, ist eine kleine Menge Overhead hinzuzufügen, um den Zustandsautomaten usw. zu erstellen, der zur Implementierung von async/await verwendet wird.

Es ist nicht klar, warum Sie erwartet haben, dass es tatsächlich asynchron passiert, aber ich vermute, es ist ein Missverständnis dessen, was erwarten/async tatsächlich tut. Es nicht startet automatisch neue Threads für Sie - es macht es einfach viel einfacher asynchrone APIs zu erstellen und zu konsumieren.

Jetzt eine Option ist nur ReportExcelAsync in ein synchrones Methode ändern möchten (ReportExcel, eine string Rückkehr) und eine neue Aufgabe für die in der anrufenden Code zu erstellen:

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

Allerdings ist es nicht klar, dass Dies würde Ihnen tatsächlich viel nutzen. Sie schreiben eine Web-App, also ist es nicht so, dass die Antwort auf diese Weise schneller geliefert wird - Sie sind im Grunde nur shifting der Thread, der die Arbeit erledigt wird.

Sie sagen:

Da ich es brauche asynchron zu tun

... aber keine Gründe geben, warum es asynchron ausgeführt werden muss. Was ist mit dem synchronen Ansatz in diesem Fall falsch? Asynchrony ist großartig, wenn es angemessen ist, aber ich denke nicht, dass es in Ihrem Fall ist.

+0

Ist nicht, was diese Zeile var filePath = erwarten Excel.ReportExcelAsync (midyearReportViewModel); macht? 2. Zeile. – stevethethread

+1

@stevethethread: Das würde Dinge asynchron machen * wenn * 'ReportExcelAsync' wirklich asynchron wäre - aber das ist es nicht.Das ist die Methode, die die Warnung generiert, weil sie keine Ausdrücke erwartet. –

+0

@Skeet Mein Ziel war es, das Excel zu generieren und den Pfad asynchron zurückzugeben. – user2988112

Verwandte Themen