내 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);
}
이 메소드는 아래와 같이 ExcelExcelAsync 생성기 메서드를 호출합니다.
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 바운드 작업을 수행하기 위해 기다리고 있습니다.
. 뭔가 잘못하고 있는거야? 내 코드가 제대로 작동하고 다운로드 한 엑셀을 얻을 수있다.
내가 뭔가 잘못하고 있는거야?
글쎄, 당신은 실제로 비동기 적으로 아무것도하지 않습니다. 너의ReportExcelAsync
메소드는 완전히 동기식입니다.await
표현. 그래서GenerateReportExcel
전화 할 것이다.ReportExcelAsync
, 동기식으로 실행 한 다음 완료된 태스크를 리턴합니다. 현재 당신이 수행 한 것은 상태 머신 등을 만들기위한 약간의 오버 헤드를 추가하는 것입니다.async
/await
.
왜 비동기 적으로 실제로 일어날 것이라고 예상했는지는 명확하지 않지만 실제로 / async가 실제로 기다리는 것이 오해 된 것 같습니다. 그것하지 않는다자동으로 새 스레드를 시작하십시오. 비동기 API를 만들고 사용하는 것이 훨씬 쉬워집니다.
이제는 하나의 옵션으로 변경하고 싶을뿐입니다.ReportExcelAsync
동기 방식으로ReportExcel
,string
) 호출 코드에서 해당 작업을 새로 작성하십시오.
var filePath = await Task.Run(excel.ReportExcel);
그러나 이것이 실제로 많은 이점을 줄 것이라고는 분명하지 않습니다. 웹 앱을 작성하고 있으므로 응답이 이렇게 빨리 전달되지는 않습니다. 사실,이동작업이 끝난 스레드.
너는 이렇게 말한다 :
비동기로 수행해야하므로
...하지만 아무 이유도주지 말라.왜비동기 적으로 수행되어야합니다. 이 경우 동기식 접근 방식의 문제점은 무엇입니까? 비동기는 적절할 때 좋지만, 나는 그것이 당신의 경우라고 생각하지 않습니다.
ReportExcelAsync
정말 비동기 적이었습니다 -하지만 그렇지는 않습니다. 경고가 생성되는 방법은 경고를 생성하는 방법입니다.await
표현. - Jon Skeet