c# - ConfigureAwait(true) 是否总是返回到原始线程,即使被调用方方法在内部执行 ConfigureAwait(false)?

标签 c# asynchronous async-await configureawait

<分区>

我期待回到位置 1.2 处的线程#1,但我没有。有没有办法在进行异步调用后返回到 UI 线程?谢谢

我也不能使顶级方法异步。不确定完全异步是否能解决这个问题,但我现在没有那个选择。

class Program
{
    static void Main(string[] args)
    {
        ComputeThenUpdateUI().Wait();
    } 
    static async Task ComputeThenUpdateUI()
    {
        Console.WriteLine($"1.1 {Thread.CurrentThread.ManagedThreadId}");
        await ExpensiveComputingNonUI().ConfigureAwait(true);
        Console.WriteLine($"1.2 {Thread.CurrentThread.ManagedThreadId}");
    } 
    static async Task ExpensiveComputingNonUI()
    {
        Console.WriteLine($"2.1 {Thread.CurrentThread.ManagedThreadId}");
        await Task.Delay(3000).ConfigureAwait(false);
        Console.WriteLine($"2.2 {Thread.CurrentThread.ManagedThreadId}");
        await Task.Delay(3000).ConfigureAwait(false);
        Console.WriteLine($"2.3 {Thread.CurrentThread.ManagedThreadId}");
    }
}
 
 
Output:
1.1 1
2.1 1
2.2 4
2.3 4
1.2 4

最佳答案

回复:.ConfigureAwait(true) 是否意味着等待完成后流程将返回到同一线程?

不,在大多数情况下,无法保证。 Stephen Cleary有一个明确的答案:

This "context" is SynchronizationContext.Current unless it is null, in which case it is TaskScheduler.Current. (If there is no currently-running task, then TaskScheduler.Current is the same as TaskScheduler.Default, the thread pool task scheduler).

It's important to note that a SynchronizationContext or TaskScheduler does not necessarily imply a particular thread. A UI SynchronizationContext will schedule work to the UI thread; but the ASP.NET SynchronizationContext will not schedule work to a particular thread.

即仅从例如 UI 线程发出的调用WPF 或 Windows 窗体保证返回到同一线程。如果你真的需要返回同一个线程,那么你需要做 customization to ensure the continuation is scheduled on the original thread .

除非这是必需的(例如对于 UI 线程),否则返回到同一线程通常是不可取的,因为这会降低性能(如果存在线程争用)和 lead to deadlocks

回复:无法使顶层主方法异步

这现在可以在 C#7.1 中实现:

public static async Task Main(string[] args)
{
    // Can await asynchronous tasks here.
}

关于c# - ConfigureAwait(true) 是否总是返回到原始线程,即使被调用方方法在内部执行 ConfigureAwait(false)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50616284/

相关文章:

c# - 当我不知道 Moq 中方法的参数是什么时如何验证方法被调用

c# - 将 xml 文件保存在用户给定的路径并从那里再次加载它

c# - 您可以使用 Task.Run 将受 CPU 限制的工作移至后台线程

node.js - 在 nodejs 中重用 postgresql 连接池

c# - 在异步任务完成之前返回

c# - 是否可以仅在扩展内部满足条件时才调用方法?

c# - ASP.NET Identity Token Methods 接受所有 HTTP 方法

java - 方法内出现 AsyncCallback 的 GWT Java 错误

python - 这个多线程函数是异步的吗

visual-studio - 如何阻止 Visual Studio 11 Beta 异步操作方法挂起