【发布时间】:2021-11-08 09:07:47
【问题描述】:
阅读了/很多/关于异步等待模式的文档后,我认为我对该模式有了很好的掌握。我一直阅读有关异步的所有内容,然后阅读另一篇文章,其中提到“如果它在 50 毫秒内运行,则不要异步它”。似乎存在相互矛盾的信息和/或意见,我已经设法让自己感到困惑。我还读到 Task.Yield() 将强制异步修饰方法异步运行。
给定以下代码:
static async Task MethodA() {
await MethodB().ConfigureAwait(false);
}
static async Task MethodB() {
await Task.Yield();
MethodC();
}
static void MethodC() {
// do some synchronous stuff
}
static async Task Main(string[] args) {
var task1 = Task.Run(() => MethodA().ConfigureAwait(false));
var task2 = Task.Run(() => MethodB().ConfigureAwait(false));
await Task.WhenAll(new List<Task>() { task1, task2 });
}
MethodC 是同步运行还是异步运行,我假设它是异步的,因为它是从异步方法调用的。另外,Task.Yield 是否必要?
老实说,这让我很头疼,我读过的每一篇文章都深入探讨了异步等待模式以及原因和原因,只是增加了问题的复杂性。只是在寻找一个简单的答案。
【问题讨论】:
-
“我还读到 Task.Yield() 将强制异步修饰的方法异步运行”请告诉我你在哪里读到的。
-
Task.Yield可用于分解异步操作,否则可能会阻塞 调用者的线程,即您想推迟它和/或将它传递给线程池;因为MethodB()是通过Task.Run调用的,它已经在线程池中,因此使用Task.Yield没有任何用处。还需要注意的是,异步和并发是非常不同的概念。你的task1/task2设置演示了并发性,而不是真正的async- 因为这里没有真正的真正的async发生 -
@IanKemp 至少是真的;根据定义,
Task.Yield为IsCompleted返回报告false的内容,并且通常会通过线程池重新激活,因此:从这个角度来看:是的,它将采用一个否则会同步运行的方法(意思是:它会返回一个已经完成的等待对象),而不是返回一个不完整的等待对象,这意味着:它将被归类为完全异步。请注意,这并不一定意味着这些术语可能意味着 OP。 -
更简单的接受是,如果您调用返回
Task的方法,则该任务可能会或可能不会在方法调用返回时完成,您需要使用Task来确定当它完成时。 方法如何实现,从调用代码的角度来看,它可能会或可能不会安排Task稍后完成在很大程度上无关。 -
@IanKemp Task.Yield() stackoverflow.com/questions/22645024/…
标签: c# .net-core async-await