Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backgroundworker and TPL's Task have the same ManagedThreadID?

I have a Backgroundworker whose purpose is to run jobs sequentially in the background. Now one job is implemented in multithreading way. That mean, the Backgroundworker will create several threads. I use Task Parallel Library so I use the Task.Factory.StartNew to create multiple Tasks.

After the tasks are run, the Backgroundworker waits all of them to finish.

Now I print the Backgroundworker's ManagedThreadID and all the tasks' ManagedThreadIDs. I found that the BackgroundWorker's ManagedThreadID is always the same as the first task's ManagedThreadID. I think this shouldn't happen so I cannot explain. I think the Backgroundworker's thread must be different to all the tasks it creates so the ManagedThreadIDs must be all different from each other.

Can anyone explain why this scenario happens? Thank you very much.

Edit:

The code is similar to this:

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();
}

You will find that one task has the same ManagedThreadID as the Backgroundworker.

like image 554
Steve Avatar asked Dec 28 '22 07:12

Steve


1 Answers

I would go on a limb here and guess that the TPL is smart enough to reuse the BackgroundWorker thread. Since the worker waits for all tasks to complete running one task in the same thread is probably an optimization.

From further investigation, what you are seeing is a result of the expected behaviour of the Task.Wait method. You can read more at Task.Wait and "Inlining" on the Parallel Programming Team blog.

If the Task being Wait’d on has already started execution, Wait has to block. However, if it hasn’t started executing, Wait may be able to pull the target task out of the scheduler to which it was queued and execute it inline on the current thread.

like image 80
João Angelo Avatar answered Jan 23 '23 11:01

João Angelo