【发布时间】:2017-09-01 15:33:14
【问题描述】:
尝试在类析构函数中运行异步操作失败。
这是代码:
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 未提及实例销毁的线程/异步方面。
有什么想法吗?
谢谢
【问题讨论】:
-
Task.Run将启动另一个线程,但即使您等待 1 秒也可能还不够。您需要等待任务的结果,可能使用.Wait()来确保它完成。也就是说,我认为在析构函数中启动线程或任务是一个坏主意。应该使用析构函数来清理非托管内存。 -
哇,在 GC 之后将引用传递给另一个线程的想法显然已经将该引用放入终结器队列中......
-
@RenéVogt 文档明确提到析构函数中的代码在完成对象之前执行。看到这个锚的底部:msdn.microsoft.com/en-us/library/66x5fx1b.aspx#Remarks
-
我并没有说这是不可能的,但是 - 好吧 - 奇怪......在你的例子中,析构函数不是由 gc 调用的(afaik),而是因为你的程序终止了。我不确定
Task.Run()在执行/终止时是否真的能够从线程池中获取线程。 -
@RenéVogt 当然 - 我完全理解你的观点,你是对的,这个案例是指非常具体的情况,导致我提出这个问题,因为我找不到任何相关信息。感谢您的 cmets :)
标签: c# asynchronous destructor