加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 08:31:30 所属栏目:百科 来源:网络整理
导读:如何使用VS C#2015调试器检查线程是否返回到线程池? 在我的情况下,有问题的是它无法通过逐行调试来检测. async Task foo(){ int y = 0; await Task.Delay(5); // (1) thread 2000 returns to thread pool here... while (y5) y++;}async Task testAsync(){
如何使用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来自并返回到线程池.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读