c# - 析构函数中的异步操作

标签 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没有提及实例销毁的线程/异步方面。

有什么想法吗?

谢谢

最佳答案

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

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

并在 Release模式下进行优化编译 - 您将看到现在运行时不会终止,您的任务将正常运行。

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

关于c# - 析构函数中的异步操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43257958/

相关文章:

c# - 如何使用 Entity Framework Core 运行迁移 SQL 脚本

javascript - Node.js - 在另一个方法完全执行后调用一个方法

php - __destruct() 和 __call() 创建无限循环

c++ - 使用继承在 C++ 中调用析构函数和销毁成员变量的顺序是什么?

c++ - 如何处理 DLL 导出接口(interface)中的析构函数

c# - 使用 .NET 格式化大数

c# - 如何解决另一个进程正在使用的文件?

C#:使用 FileSystemWatcher 监视文件的更改

c# - 对async/await函数的误解

asynchronous - 进行地面AsyncTask