微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 检查线程是否返回到线程池

如何使用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.一旦遇到等待Task.Delay(5),线程2000返回到线程池(据称,我正在尝试确认这一点),并且该方法等待Task.Delay(5)完成.同时,控件返回给调用者,并且第一个testAsync循环也在线程2000上执行.

因此,在两个连续的代码行之间,线程返回到线程池并从那里返回.如何使用调试器确认?可能使用Threads调试器窗口?

为了澄清我的要求:foo在线程2000上运行.有两种可能的情况:

>当它命中等待Task.Delay(5)时,线程2000返回线程池很短的时间,并且控件返回到调用者,在第(2)行,它将在从线程池获取的线程2000上执行.如果这是真的,则无法轻松检测到它,因为Thread 2000在两个连续代码行之间的时间段内位于线程池中.
>当它命中等待Task.Delay(5)时,线程2000不会返回到线程池,而是立即从第(2)行开始执行testAsync中的代码

我想验证哪一个真的发生了.

解决方法

你的假设有一个重大错误

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块,然后等待任务.此时,如果任务尚未完成,并且假设等待其余代码,则线程2000将返回到线程池.否则,如果任务已经完成,它将同步从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.
}

请注意,在上面的情况下,线程没有返回到线程池 – 它完全被OS挂起.

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来自并返回到线程池.

原文地址:https://www.jb51.cc/csharp/243890.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐