当前位置:  开发笔记 > 编程语言 > 正文

为什么调用方法和异步方法具有相同的线程ID

如何解决《为什么调用方法和异步方法具有相同的线程ID》经验,为你挑选了1个好方法。

请参考下面的代码.

public MainViewModel()
    {
        LongRunningOperationCommand = new RelayCommand(ExecuteLongRunningOperationCommand);
    }

    private void ExecuteLongRunningOperationCommand()
    {
        Test();
    }

    private async Task Test()
    {
        Log += "Command begin: " + DateTime.Now + "\r\n";
        Log += "Command thread: " + Thread.CurrentThread.ManagedThreadId + "\r\n";
        var getStringAsync = GetStringAsync();
        Log += "Work in Command...\r\n";
        Log += "Work in Command which not related to the result of async method will complete: " + DateTime.Now + "\r\n";
        Log += "Work in Command which not related to the result of async method will complete, thread: " +
               Thread.CurrentThread.ManagedThreadId + "\r\n";
        string result = await getStringAsync;
        Log += "Command will complete: " + DateTime.Now + "\r\n";
        Log += "Command will complete, thread: " + Thread.CurrentThread.ManagedThreadId + "\r\n";
        Log += result + "\r\n";
    }

    private async Task GetStringAsync()
    {
        Log += "Async method begin: " + DateTime.Now + "\r\n";
        Log += "Async method thread: " + Thread.CurrentThread.ManagedThreadId + "\r\n";
        Log += "Work in Async method... \r\n";
        await Task.Delay(10000);
        Log += "Async method will complete: " + DateTime.Now + "\r\n";
        Log += "Async method will complete, thread: " + Thread.CurrentThread.ManagedThreadId + "\r\n";
        return "GetStringAsync method completed!";
    }

结果如下

Command begin: 1/6/2016 11:58:37 PM
Command thread: 8
Async method begin: 1/6/2016 11:58:37 PM
Async method thread: 8
Work in Async method... 
Work in Command...
Work in Command which not related to the result of async method will complete: 1/6/2016 11:58:37 PM
Work in Command which not related to the result of async method will complete, thread: 8
Async method will complete: 1/6/2016 11:58:47 PM
Async method will complete, thread: 8
Command will complete: 1/6/2016 11:58:47 PM
Command will complete, thread: 8
GetStringAsync method completed!

在GetStringAsync方法中等待Task.Delay之后的线程id应该与之前不同.为什么结果是一样的?在控制台应用程序中,线程ID是不同的,但在WPF应用程序中,它们是相同的.有人可以帮忙吗?



1> Scott Chambe..:

async/await的一个重点是,如果你有一个SynchronizationContext,比如WPF DispatcherSynchronizationContext,那么在await之后,该线程上的工作将在该线程上继续,除非你告诉它不要.

控制台应用程序没有SynchronizationContext,因此它使用默认上下文来调度线程池上的线程,这就是您从WPF和控制台应用程序中看到不同行为的原因.

要告诉async/await它不需要保持在.ConfigureAwait(false)等待时可以使用的同一个同步上下文,它将使用默认线程池上下文在需要时进行回调.

private async Task Test()
{
    Log += "Command begin: " + DateTime.Now + "\r\n";
    Log += "Command thread: " + Thread.CurrentThread.ManagedThreadId + "\r\n";
    var getStringAsync = GetStringAsync();
    Log += "Work in Command...\r\n";
    Log += "Work in Command which not related to the result of async method will complete: " + DateTime.Now + "\r\n";
    Log += "Work in Command which not related to the result of async method will complete, thread: " +
           Thread.CurrentThread.ManagedThreadId + "\r\n";
    string result = await getStringAsync.ConfigureAwait(false);
    Log += "Command will complete: " + DateTime.Now + "\r\n";
    Log += "Command will complete, thread: " + Thread.CurrentThread.ManagedThreadId + "\r\n";
    Log += result + "\r\n";
}

private async Task GetStringAsync()
{
    Log += "Async method begin: " + DateTime.Now + "\r\n";
    Log += "Async method thread: " + Thread.CurrentThread.ManagedThreadId + "\r\n";
    Log += "Work in Async method... \r\n";
    await Task.Delay(10000).ConfigureAwait(false);
    Log += "Async method will complete: " + DateTime.Now + "\r\n";
    Log += "Async method will complete, thread: " + Thread.CurrentThread.ManagedThreadId + "\r\n";
    return "GetStringAsync method completed!";
}

注意,.ConfigureAwait(false)如果任务处于Completed状态,代码将同步执行并保留在最初调用的任何线程上,则不保证其余代码将位于线程池中await.

有关详细信息,请参阅artice" 它是关于SynchronizationContext的全部内容 ".

推荐阅读
yzh148448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有