Trying to run async operation in class destructor is fail.
This is the code:
public class Executor
{
public static void Main()
{
var c1 = new Class1();
c1.DoSomething();
}
}
public class Class1
{
public void DoSomething()
{
}
private int _i = 100;
private int _j = 100;
~Class1()
{
Task.Run(() => _j *= 2); //Does not progress _j
_i *= 2; //Progress _i from 100 to 200
Thread.Sleep(1000);
Console.WriteLine("In destructor. _i = " + _i);
Console.WriteLine("In destructor. _j = " + _j);
}
}
And the output is:
In destructor. _i = 200
In destructor. _j = 100
Following Destructor page on MSDN does not mention threads/async aspects of instance destruction.
So any ideas?
Thank you
In your particular example new thread cannot be started because runtime is terminating and app domain is unloading. When app domain unloads - it will run all finalizers and shutdown all threads. You can verify this with:
Console.WriteLine("shutdown:" + Environment.HasShutdownStarted);
Which will return true in your case. If you modify you example like this:
class Program {
static void Main(string[] args) {
var c1 = new Class1();
c1.DoSomething();
GC.Collect();
GC.WaitForPendingFinalizers();
Console.ReadKey();
}
}
public class Class1
{
public void DoSomething()
{
}
private volatile int _i = 100;
private volatile int _j = 100;
~Class1()
{
Console.WriteLine("shutdown:" + Environment.HasShutdownStarted);
Task.Run(() => _j *= 2); //Does not progress _j
//_i *= 2; //Progress _i from 100 to 200
Thread.Sleep(1000);
Console.WriteLine("In destructor. _i = " + _i);
Console.WriteLine("In destructor. _j = " + _j);
}
}
And compile in Release mode with optimizations - you will see that now runtime is not terminating and your task will run fine.
Obviously you should never do such things in finalizer, but just so that you know the real reason.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With