Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can .NET Task instances go out of scope during run?

If I have the following block of code in a method (using .NET 4 and the Task Parallel Library):

var task = new Task(() => DoSomethingLongRunning()); task.Start(); 

and the method returns, will that task go out of scope and be garbage collected, or will it run to completion? I haven't noticed any issues with GCing, but want to make sure I'm not setting myself up for a race condition with the GC.

like image 300
Hank Avatar asked May 06 '10 16:05

Hank


People also ask

How do tasks work in C#?

A Task represents some asynchronous operation and is part of the Task Parallel Library, a set of APIs for running tasks asynchronously and in parallel. The task can return a result. There is no direct mechanism to return the result from a thread. Task supports cancellation through the use of cancellation tokens.

Can you await a Task twice?

await hides all this complexity from you, and it allows you to await the same task in ten different places (very useful for e.g. asynchronous lazy initialization). can I be assured that the method pointed by task wont be executed twice even if the task is running or ran already ? @BilalFazlani Yes, you can.

Does Task run Use thread pool?

The main purpose of Task. Run() is to execute CPU-bound code in an asynchronous way. It does this by pulling a thread from the thread pool to run the method and returning a Task to represent the completion of the method.

Does Task run block thread?

Run is misused to run IO blocking tasks. Although the code will work just fine (e.g UI not not freeze) but it is still a wrong approach. This is because Task. Run will still block a thread from thread pool the entire time until it finishes the method.


2 Answers

Update:

After I answered this question (a long time ago!) I found out that it's not true that Tasks will always run to completion - there's a small, let's say "corner" case, where tasks may not finish.

The reason for that is this: As I have answered previously, Tasks are essentially threads; but they are background threads. Background threads are automatically aborted when all foreground threads finish. So, if you don't do anything with the task and the program ends, there's a chance the task won't complete.

You should always await on tasks. More information can be found on the excellent answer Jon gave me.


Original:

Task are scheduled to the ThreadPool, meaning that they are essentially threads¹ (actually, they encapsulate threads).

From the Thread documentation:

It is not necessary to retain a reference to a Thread object once you have started the thread. The thread continues to execute until the thread procedure is complete.

So, no, there is no need to retain a reference to it.

Also, the documentation states that the preferred way to create a Task is to use it's factory:

You can also use the StartNew method to create and start a task in one operation. This is the preferred way to create and start tasks if creation and scheduling do not have to be separated (...)

Hope it helps.


¹ Accordingly to the documentation:

A task represents an asynchronous operation, and in some ways it resembles the creation of a new thread or ThreadPool work item, but at a higher level of abstraction.

like image 134
Bruno Brant Avatar answered Sep 27 '22 23:09

Bruno Brant


The task will run to completion. Even if there aren't any other references to it (not being rooted I believe is the term), the thread pool will still hold a reference to it, and prevent it from being Garbage Collected at least (I say at least, because even after it completes, there is no guarantee that it will be Garbage Collected) until completion.

like image 43
kemiller2002 Avatar answered Sep 27 '22 21:09

kemiller2002