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

标签 c# multithreading debugging async-await

如何使用 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/

相关文章:

java - 如何阻止同一个线程运行多个实例

java - 如何在谷歌地图上添加矩形框?

debugging - 如何在 Haskell 中获取调用堆栈?

c# - Model.Is___ - 它应该是属性还是方法?

c# - 如何只获取可以复制的文件?

C# 和 Oracle 数字数据类型

python - 如何在多线程环境中使用requests-html渲染异步页面?

c# - 查询数据库的问题 - 仅适用于我的电脑

c - 以基本方式使用线程的段错误

javascript - Node.js 行被跳过然后被处理