gpt4 book ai didi

c# - 检查线程是否返回线程池

转载 作者:太空狗 更新时间:2023-10-29 21:26:58 29 4
gpt4 key购买 nike

如何使用 VS C# 2015 调试器检查线程是否返回到线程池?

我的问题是无法通过逐行调试检测到它。

async Task foo()
{
int y = 0;
await Task.Delay(5);
// (1) thread 2000 returns to thread pool here...
while (y<5) y++;
}

async Task testAsync()
{
Task task = foo();
// (2) ... and here thread 2000 is back from the thread pool, to run the code below. I want
// to confirm that it was in the thread pool in the meantime, using debugger.
int i = 0;
while (i < 100)
{
Console.WriteLine("Async 1 before: " + i++);

}
await task;
}

在线程2000上运行的testAsync的第一行调用了foo。一旦遇到await Task.Delay(5),线程2000返回线程池(据说,我正在尝试确认这一点),方法等待Task.Delay(5) 来完成。与此同时,控制权返回给调用者,testAsync 的第一个循环也在线程 2000 上执行。

于是在连续的两行代码之间,线程又回到了线程池,又从那里回来了。我如何用调试器确认这一点?可能使用 Threads 调试器窗口?

为了进一步澄清我的问题:foo 正在线程 2000 上运行。有两种可能的情况:

  1. 当它命中 await Task.Delay(5) 时,线程 2000 会在很短的时间内返回到线程池,并且控制权返回给调用者,在第 (2) 行,它将在从线程池中获取的线程 2000 上执行。如果这是真的,您将无法轻易检测到它,因为线程 2000 在连续两行代码之间期间位于线程池中。

  2. 当它命中 await Task.Delay(5) 时,线程 2000 不会返回到线程池,而是立即从 line 开始执行 testAsync 中的代码(2)

我想验证哪一个是真实发生的。

最佳答案

你的假设有一个重大错误:

When it hits await Task.Delay(5), thread 2000 returns to the thread pool

因为你不等待 foo()然而,当线程 2000 命中 Task.Delay(5) 时它只是创建一个新的 Task并返回到 testAsync() (至 int i = 0;)。它移动到 while block ,然后你才等待 task .此时,如果task尚未完成,假设等待其余代码,线程 2000 将返回到线程池。否则,如果 task已经完成,将从foo()开始同步继续(位于 while (y<5) y++;)。

编辑:

what if the main method called testAsync?

当同步方法调用并等待异步方法时,如果异步方法返回未完成的任务,则必须阻塞线程:

void Main()
{
var task = foo();
task.Wait(); //Will block the thread if foo() is not completed.
}

请注意,在上述情况下,线程不会返回线程池 - 它已完全被操作系统挂起。

Maybe you can give an example of how to call testAsync so that thread 2000 returns to the thread pool?

假设线程2k是主线程,不能返回线程池。但是你可以使用 Task.Run(()=> foo())运行 foo()在线程池上,并且由于调用线程是主线程,另一个线程池线程将接管该任务。所以下面的代码:

static void Main(string[] args)
{
Console.WriteLine("main started on thread {0}", Thread.CurrentThread.ManagedThreadId);
var testAsyncTask = Task.Run(() => testAsync());
testAsyncTask.Wait();
}
static async Task testAsync()
{
Console.WriteLine("testAsync started on thread {0}", Thread.CurrentThread.ManagedThreadId);
await Task.Delay(1000);
Console.WriteLine("testAsync continued on thread {0}", Thread.CurrentThread.ManagedThreadId);
}

(在我的电脑上)产生了以下输出:

main started on thread 1
testAsync started on thread 3
testAsync continued on thread 4
Press any key to continue . . .

线程 3 和 4 来自线程池并返回线程池。

关于c# - 检查线程是否返回线程池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33718163/

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