Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 配置等待和GetWaiter更改行为_C#_Task - Fatal编程技术网

C# 配置等待和GetWaiter更改行为

C# 配置等待和GetWaiter更改行为,c#,task,C#,Task,我正在试验各种任务。 我有 我希望最后一行没有死锁和崩溃,因为没有UI上下文,如果我没有使用GetWaiter(),我会遇到死锁 下一步: 在这里,由于非UI上下文,我预计最后一行会崩溃,但它可以正常工作。 当我们使用GetAwaiter()时,ConfigureAwait(false)是否有意义?ConfigureAwait在同一表达式中配置await关键字的行为。它不会影响其他方法中的其他await语句,如果不使用await,则不会产生任何效果 它控制await语句是否捕获当前同步上下文(如

我正在试验各种任务。 我有

我希望最后一行没有死锁和崩溃,因为没有UI上下文,如果我没有使用GetWaiter(),我会遇到死锁

下一步:

在这里,由于非UI上下文,我预计最后一行会崩溃,但它可以正常工作。
当我们使用GetAwaiter()时,ConfigureAwait(false)是否有意义?

ConfigureAwait
在同一表达式中配置
await
关键字的行为。它不会影响其他方法中的其他
await
语句,如果不使用
await
,则不会产生任何效果

它控制
await
语句是否捕获当前同步上下文(如果有)。实际上,如果在UI线程上运行
await
语句,则
await任务
也将在UI线程上的
等待
之后运行代码,而
等待任务。ConfigureAwait(false)
将在线程池线程上的
等待
之后运行代码

在您的第一个示例中:

private async Task<string> GetStringWithInnerCallConfigureAwaitFalseAsync()
{
    await Task.Delay(3000).ConfigureAwait(false);
    return "Finished!"; // <-- Run on the thread pool
}

private async Task<string> GetStringAsync()
{
    await Task.Delay(3000);
    return "Finished!"; // <-- Run on the captured SynchronizationContext (if any)
}
调用
ConfigureAwait
在这里什么也不做,因为您没有等待结果。您可以不做任何更改就将其删除

var result = task.GetResult(); // deadlock
运行
GetStringAsync
中的
return
语句需要UI线程。由于在调用
GetResult()
时阻止了它,因此它无法完成
GetStringAsync
方法,因此出现了死锁


在调用
GetStringWithInnerCallConfigureAwaitFalseAync
的第二个代码段中:

var task = GetStringAsync().ConfigureAwait(false).GetAwaiter();
var task = GetStringWithInnerCallConfigureAwaitFalseAsync().ConfigureAwait(false).GetAwaiter();
同样,对
ConfigureAwait(false)
的调用不起任何作用,因为您没有等待结果

var result = task.GetResult(); // No deadlock
这一次,
getStringWithInnerCallConfigureAwaitFalseAync
不执行
await…ConfigureAwait(false)
,因此
await
之后的代码在线程池上运行,而不是在UI线程上运行。因此,不需要UI线程来完成此方法,因此您可以安全地(!)阻止它

Button11.Content = result; // No crash

您在UI线程上调用了此方法,并且从未离开过它-您同步调用所有内容,没有
wait
s等。因此,此时您仍在UI线程上

谢谢,解释得很好!关键短语是,如果您不使用wait,它将无效。
var task = GetStringWithInnerCallConfigureAwaitFalseAsync().ConfigureAwait(false).GetAwaiter();
var result = task.GetResult(); // No deadlock
Button11.Content = result; // No crash