从同步上下文转移到异步上下文的最佳方法是什么?如果父方法不知道如何等待任何东西,但你想异步运行一些东西,那么最好的使用方法是什么?似乎他们写道 async void 是一种不好的做法,因为它没有控制任务,启动它 - 并且不清楚接下来会发生什么。但是从同步方法启动任务时结果不一样吗?他没有等她,发射——然后忘记了。
一般来说,任务是从同步方法中启动一个异步方法,如何最正确地做到这一点?
class Hello
{
static void Main(string[] args)
{
SomeVoidMethod();
SomeTaskMethod();
}
async void SomeVoidMethod()
{
}
async Task SomeTaskMethod()
{
return Task.CompletedTask;
}
}
在这种特殊情况下,没关系,因为您不使用
await,并且Task根本不编译的那个,并且 main 不会编译,您至少应该在将代码插入问题之前检查代码.并且显示的两种方法都是同步的。不会
async使方法异步,但是await.async void- 这是一种“一劳永逸”的方法,也就是说,你启动一个异步操作,然后你不会以任何方式跟踪它,如果在那里抛出异常,那么它充其量会随着操作的某个地方而死线程池,最坏的情况是它会使上下文同步崩溃,你会想知道到底发生了什么以及如何捕获这个异常。因此,只有
await且只有Task。从主目录中删除
await它,您将看不到控制台的输出。不可预测的代码行为总是不好的。如果您需要“启动并忘记”
async void,那么您绝对应该处理异常并考虑到该方法将在您无法控制的时间完成工作。也就是说,应用程序至少应该比这种方法运行更长的时间。从主目录中删除
Console.ReadKey()它,您将看不到控制台的输出。代码的不可预测的行为 - 好吧,你明白了。现在像这样
在执行可能重要的代码期间,此方法会使您的应用程序崩溃。突然间,main 将某些内容写入磁盘,例如,保存用户数据。对于 main 来说,一切都很好,但是方法中抛出的异常
async void会丢弃整个应用程序,即使你将它包装在 . 中try-catch,它也无济于事。尝试在不更改方法本身的代码的情况下捕获异常 - 你不会成功。顺便说一句,如果在这个例子中你void将它替换为Task,那么异常将陷入深渊,你根本看不到它,它根本不起作用,你不会知道它并寻找了很长时间,找了半天原因。因此,在方法中捕获异常
async void是一个强制性的过程。如果要捕获方法外的异常,请使用
async Taskandawait。关于
然后不要在类构造函数中编写代码,而是在异步方法中编写代码。
而且您不必从同步方法运行异步方法。对于各种 winforms 中的事件处理程序
async void,以及如何使用它 - 我在上面展示了。读: