- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
如何使用 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 上运行。有两种可能的情况:
当它命中 await Task.Delay(5)
时,线程 2000 会在很短的时间内返回到线程池,并且控制权返回给调用者,在第 (2) 行,它将在从线程池中获取的线程 2000 上执行。如果这是真的,您将无法轻易检测到它,因为线程 2000 在连续两行代码之间期间位于线程池中。
当它命中 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/
我是一名优秀的程序员,十分优秀!