gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 19:55:02 25 4
gpt4 key购买 nike

请引用我下面的代码。

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<string> 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 方法中 await Task.Delay 之后的线程 id 应该与之前不同。为什么结果是一样的?在控制台应用程序中,线程 ID 不同,但在 WPF 应用程序中,它们是相同的。谁能帮忙?

最佳答案

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<string> 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 的任何线程上。

有关详细信息,请参阅文章“It's All About the SynchronizationContext”。

关于c# - 为什么调用方方法和异步方法具有相同的线程 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34637447/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com