即使被调用方方法在内部执行ConfigureAwait(false),ConfigureAwait(true)是否始终返回原始线程吗?

Car*_*rol 3 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
Run Code Online (Sandbox Code Playgroud)

Stu*_*tLC 5

Re:难道.ConfigureAwait(true)一旦等待完成,流将返回相同的线程吗?

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

除非为null,否则此“上下文”为SynchronizationContext.Current,在这种情况下为TaskScheduler.Current。(如果没有当前正在运行的任务,则TaskScheduler.Current与线程池任务计划程序TaskScheduler.Default相同)。

重要的是要注意,SynchronizationContext或TaskScheduler不一定暗含特定线程。UI SynchronizationContext将把工作安排到UI线程;但是ASP.NET SynchronizationContext不会将工作调度到特定线程。

即,仅保证从WPF或Windows Forms等UI线程进行的调用返回到同一线程。如果确实需要返回相同的线程,则需要进行自定义以确保在原始线程上计划了继续

除非这是必不可少的(例如对于UI线程),否则通常不希望返回相同的线程,因为这会降低性能(如果存在线程争用)并导致死锁

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

现在可以在C#7.1中实现

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