代码之家  ›  专栏  ›  技术社区  ›  Steve

Backgroundworker和TPL的任务具有相同的ManagedThreadID?

  •  3
  • Steve  · 技术社区  · 15 年前

    我有一个后台工作人员,他的目的是在后台按顺序运行作业。现在有一个作业是以多线程方式实现的。也就是说,Backgroundworker将创建几个线程。我使用任务并行库,所以我使用任务.Factory.StartNew创建多个任务。

    任务运行后,Backgroundworker将等待所有任务完成。

    现在我打印Backgroundworker的ManagedThreadID和所有任务的ManagedThreadID。我发现BackgroundWorker的ManagedThreadID始终与第一个任务的ManagedThreadID相同。我认为这不应该发生,所以我无法解释。我认为Backgroundworker的线程必须与它创建的所有任务不同,因此ManagedThreadId必须彼此不同。

    编辑:

    代码类似于:

    Backgroundworker.Run(){
        // Print Thread.CurrentThread.ManagedThreadID.
        var task = Task.Factory.StartNew(action1); // action1, action2 also print ManagedThredID.
        taskList.Add(task);
        task = Task.Factory.StartNew(action2);
        taskList.Add(task);
        ... // Several other tasks.
    
        foreach(var task in taskList) task.Wait();
    }
    

    4 回复  |  直到 15 年前
        1
  •  5
  •   João Angelo    15 年前

    我敢说,第三方物流足够聪明,可以重用 BackgroundWorker 线程。因为worker等待所有任务完成,所以在同一个线程中运行一个任务可能是一种优化。

    从进一步的调查中,你所看到的是预期行为的结果 Task.Wait Task.Wait and "Inlining" 在并行编程团队的博客上。

    已开始执行,必须等待 执行,等待可能会拉 从调度程序中删除目标任务 并执行它

        2
  •  2
  •   Darin Dimitrov    15 年前

    当然,这只是一个无法验证的假设,因为您还没有显示代码。

        3
  •  2
  •   Henk Holterman    15 年前

    创建任务时,它不会立即/永久地与线程关联。任务是放入队列中的作业,队列由工作线程提供服务。因此,可能是Bgw任务被挂起,其线程返回到池中,或者更直接地说,它可以由Wait()完成:

    // thread A
    var t1 = Task.Startnew(...);
    var t2 = Task.Startnew(...);
    t1.Wait();  // Thread A is idle/available so Wait can execute t1
    t2.Wait();  
    
        4
  •  1
  •   fab    14 年前