首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在ASP.NET内核中使用async/await on void方法?

如何在ASP.NET内核中使用async/await on void方法?
EN

Stack Overflow用户
提问于 2019-03-01 03:46:20
回答 2查看 7.2K关注 0票数 4

我正在试着进入异步的东西。我想让我的一个方法异步,因为它需要一段时间才能完成,所以我试着这样做:

public static async Task GenerateExcelFile(HashSet<string> codes, ContestViewModel model)
{
    var totalCodeToDistribute = model.NbrTotalCodes - (model.NbrCodesToPrinter + model.NbrCodesToClientService);
    if (model.NbrTotalCodes > 0)
    {
        using (var package = new ExcelPackage())
        {
                         
            await DoStuff(some, variables, here);
                        
            package.SaveAs(fileInfo);
        }
    }
}

所以我可以像这样在我的控制器中调用它:

 await FilesGenerationUtils.GenerateExcelFile(uniqueCodesHashSet, model);

但是当涉及到"await“关键字时,它会说”类型void是不可等待的“。

这是等待void方法的一种方式,还是不是一种最佳实践?如果是这样的话,最好的方法是什么?

控制器:

[HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Index(ContestViewModel model)
        {
            var contentRootPath = _hostingEnvironment.ContentRootPath;

            DirectoryUtils.OutputDir = new DirectoryInfo(contentRootPath + Path.DirectorySeparatorChar
                                                                         + "_CodesUniques" + Path.DirectorySeparatorChar
                                                                         + model.ProjectName +
                                                                         Path.DirectorySeparatorChar
                                                                         + "_Codes");
            var directory = DirectoryUtils.OutputDir;

            var selectedAnswer = model.SelectedAnswer;

            var uniqueCodesHashSet = new HashSet<string>();

            try
            {
                
                while (uniqueCodesHashSet.Count < model.NbrTotalCodes)
                {
                    var generatedString = RandomStringsUtils.Generate(model.AllowedChars, model.UniqueCodeLength);
                    uniqueCodesHashSet.Add(generatedString.ToUpper());
                }

                #region FOR TXT FILES

                if (selectedAnswer == FileExtension.TXT.GetStringValue())
                {
                   await FilesGenerationUtils.GenerateTxtFiles(uniqueCodesHashSet, model, directory);
                }

                #endregion

                #region FOR XLSX FILES

                if (selectedAnswer == FileExtension.XLSX.GetStringValue())
                {
                    await FilesGenerationUtils.GenerateExcelFile(uniqueCodesHashSet, model);
                }

                #endregion
             
       
                return View();
            }
            catch (Exception ex)
            {
                Console.Write(ex);
            }

            return View();
        }

如果我已经理解了你们所说的,我必须创建一个可以等待的方法。如果我这样做,对吗?

public static Task DoStuff(ExcelWorksheet sheet, HashSet<string> codes, int rowIndex, int count, int maxRowValue)
        {
            foreach (var code in codes)
            {
                sheet.Row(rowIndex);
                sheet.Cells[rowIndex, 1].Value = code;
                rowIndex++;
                count++;
                if (rowIndex == maxRowValue && count < (codes.Count - 1))
                {
                    sheet.InsertColumn(1, 1);
                    rowIndex = 1;
                }
            }
            //What should be returned?!
            return null;
        }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-01 04:12:36

您可以编写异步void方法,但这些方法不能等待:

public static class Program
{
    public static async Task Main()
    {
        const int mainDelayInMs = 500;
        AsyncVoidMethod();
        await Task.Delay(mainDelayInMs);
        Console.WriteLine($"end of {nameof(Main)}");
    }

    static async void AsyncVoidMethod()
    {
        await Task.Delay(1000);
        Console.WriteLine($"end of {nameof(AsyncVoidMethod)}");
    }
}

正如你所看到的,AsyncVoidMethod是异步的,但是我不能写await AsyncVoidMethod();

不应该(大多数情况下)使用异步void方法,因为您不能等待任务完成,并且抛出的任何异常都可能得不到处理(因此它会使您的应用程序崩溃):Why exactly is void async bad?

票数 6
EN

Stack Overflow用户

发布于 2019-03-01 04:01:16

当你的方法在幕后阻塞时,假装你的方法是异步的,通常没有什么好处。如果你需要一个任务,你可以在Task.Run中封装阻塞方法来创建一个可等待的任务。您仍将使用和阻塞线程,但不是当前线程。

推荐阅读:https://blog.stephencleary.com/2013/11/taskrun-etiquette-examples-using.html

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54933176

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档