考虑以下代码:
async Task Go()
{
var task1 = PrintAnswerToLife();
var task2 = PrintAnswerToLife();
await task1; await task2;
}
async Task PrintAnswerToLife()
{
var task = GetAnswerToLife();
int answer = await task; Console.WriteLine(answer);
}
async Task<int> GetAnswerToLife()
{
var task = Task.Delay(5000);
await task; int answer = 21 * 2; return answer
}
问题1:
在Albahari兄弟撰写的“坚果壳中的C#5.0 ”一书的第14章第588页中,我们指出两个异步操作task1和task2并行运行。这对我来说似乎不正确。据我了解,在var task1 = PrintAnswerToLife();
运行时,执行将进入PrintAnswerToLife()
击中的位置,await
将执行返回到Go()
,然后继续执行下一行var task1 = PrintAnswerToLife();
,再次发生相同的情况。换句话说,在的前两行中没有并行发生的事情Go()
。实际上,除非涉及到线程(如inTask.Run()
或Task.Delay()
),否则不会发生真正的并行性。我理解正确吗?如果是这样,那么阿尔巴哈里(Albarhari)所说的两个行动并行进行到底意味着什么?
问题2:
在同一页面上,Albarhari继续声明以下内容:
尽管操作的方式有所不同,但是无论操作是否在UI线程上启动,都会以这种方式创建并发。在这两种情况下,我们都会在启动它的底层操作中发生相同的并发(例如Task.Delay或植入到Task.Run的代码)。仅当在没有同步上下文的情况下启动操作时,调用堆栈中位于此之上的方法才可以接受真正的并发性。
阿尔巴哈里(Albarhari)这是什么意思?我不了解aSynchronizationContext
在这里如何发挥作用以及它有什么区别。
并行通常意味着多个线程同时处理。这里使用的更准确的术语是并发。在您的示例中,两个任务同时执行。这意味着await Task.Delay(5000)
两个任务中的异步操作(即)同时被“执行”。这就是为什么自Go
开始以来这两个任务都将完成约5秒钟的原因。如果任务将按顺序运行,则将花费10秒钟。然后,将在线程池线程上调度同步继续(假设没有特殊情况SynchronizationContext
),并且存在并行的机会。
我理解正确吗?
是的。
如果是这样,那么阿尔巴哈里(Albarhari)所说的两个行动并行进行到底意味着什么?
它们可以潜在并行并行地同时运行和异步运行。
再次说明有点简单。它指的是特定SynchronizationContext
的,即SynchronizationContext
GUI环境中使用的单线程。因为这SynchronizationContext
将所有工作安排在一个特定的线程上,所以不允许“真正的并发”。但是,还有其他多线程SynchronizationContext
s,您可以创建自己的。因此,使用aSynchronizationContext
并不一定会阻止并发(您也可以SynchronizationContext
通过ConfigureAwait(false)
在任务上使用来完全禁用捕获)
阿尔巴哈里(Albarhari)这是什么意思?
在GUI环境中,SynchronizationContext
它使用无法并行执行任何操作的单个线程。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句