Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why will an empty .NET Task not complete if started and waited for from a static constructor?

I cannot understand why the following code will not work:

var task = new Task(() => { });
task.Start();
if (task.Wait(10000))
{
   logger.Info("Works");
}
else
{  
   logger.Info("Doesn't work");
}

The task status is stuck on "Running" after the timeout expires, although there is nothing to be done. Replacing task.Start() with task.RunSynchronously() will work however.

Does anyone have an idea of what I may be doing wrong?

A test project to replicate the issue is available here: http://erwinmayer.com/dl/TaskTestProject.zip. As far as I can see, it doesn't work if the method with the above code runs within the static constructor. But it works if called directly as a static class method.

This recent MSDN blog post seems to highlight related issues with static constructors: http://blogs.msdn.com/b/pfxteam/archive/2011/05/03/10159682.aspx

like image 408
Erwin Mayer Avatar asked Dec 21 '11 19:12

Erwin Mayer


People also ask

Why do we need static constructor in C#?

A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed only once. It is called automatically before the first instance is created or any static members are referenced.

Can constructor be static in c# net?

Prerequisite: Constructors in C# Static constructors are used to initialize the static members of the class and are implicitly called before the creation of the first instance of the class. Non-static constructors are used to initialize the non-static members of the class.

Which constructor is called first in C# static or default?

A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed once only. It is called automatically before the first instance is created or any static members are referenced.

Can we have static constructor in non static class in C#?

Also, you can have a static constructor in a static class or a non-static class. A static constructor is used to initialize the static members of a class. The static constructor of a class is invoked the first time a static member of the class is accessed.


2 Answers

The context is very important here. When you start a task like this, it uses the current scheduler - and if that assumes it will be able to use the current thread, you'll effectively deadlock when you wait for it.

The same code in different context would be fine.

The reason others are saying it's working for them, but it's not working for you, is that no doubt you're running this code in a different context to other people - but you haven't shown us a short but complete program, just this snippet, so everyone is trying to reproduce it in a different way. (I see you've now uploaded a project, which will no doubt shed more light. A short but complete program which could be posted in the question is generally preferable, of course.)

like image 112
Jon Skeet Avatar answered Sep 21 '22 10:09

Jon Skeet


Thank you everyone for your comments, it helped me be more specific and finally isolate the issue.

I created a test project here: http://erwinmayer.com/dl/TaskTestProject.zip. It shows that the code in my question doesn't work if it runs within the static constructor. But it does work if called directly as a static class method, after the static constructor has been initialized.

This recent MSDN blog post provides some technical insight on the existence of related issues when dealing with multithreading and static constructors:

like image 39
Erwin Mayer Avatar answered Sep 18 '22 10:09

Erwin Mayer