析构函数中的异步操作

时间:2017-04-06 14:22:02

标签: c# asynchronous destructor

尝试在类析构函数中运行异步操作失败。

这是代码:

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

输出是:

In destructor. _i = 200
In destructor. _j =  100

以下Destructor page on MSDN未提及实例销毁的线程/异步方面。

所有想法?

谢谢

1 个答案:

答案 0 :(得分:2)

在您的特定示例中,无法启动新线程,因为运行时正在终止且app域正在卸载。当app域卸载时 - 它将运行所有终结器并关闭所有线程。您可以通过以下方式验证:

Console.WriteLine("shutdown:" + Environment.HasShutdownStarted);

在您的情况下会返回true。如果你修改了这样的例子:

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

在发布模式下使用优化进行编译 - 您将看到现在运行时没有终止,您的任务运行正常。

显然你不应该在终结者中做这些事情,只是为了让你知道真正的原因。