c# - 如何在 ASP.NET Core 中的 void 方法上使用 async/await?
问题描述
我试图进入异步的事情。我想让我的一种方法异步,因为它需要一段时间才能完成,所以我尝试了这个:
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;
}
解决方案
您可以编写 async 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();
。
Async void 方法(大多数时候)不应该被使用,因为你不能等待任务完成,并且抛出的任何异常都可能不会被处理(因此它可能会使你的应用程序崩溃):为什么 void async 不好?
推荐阅读
- javascript - 你能用变量在 LocalStorage 中保存一些东西吗?
- python - 在 tensorflow 中训练一个 Bert 词嵌入模型
- python - 如何使用停止按钮停止循环?
- r - 正则表达式在 tidyr::extract 的小数点后找不到零。你能猜出原因吗?
- java - Appium:如何在不使用模拟器上的图库的情况下从 android 模拟器上的相机捕获上传的图像
- python - Kivy Buildozer:AttributeError:“NoneType”对象没有属性“文本”
- java - TSP 的蚁群优化没有得到最短路径
- excel - 遍历列并且只取项目一次
- mysql - 两个表上的内部连接的mysql语法错误
- clojure - Clojure 函数/宏应用函数,直到返回 nil 以外的值