Roy*_*mir 10 .net c# clr garbage-collection finalizer
class Program : CriticalFinalizerObject
{
static void Main(string[] args)
{
Program p = new Program();
TextWriterTraceListener listener = new TextWriterTraceListener(@"C:\trace.txt");
Trace.Listeners.Clear(); // Remove default trace listener
Trace.Listeners.Add(listener);
Trace.WriteLine("First Trace"); // Generate some trace messages
Trace.WriteLine("Perhaps last Trace.");
}
~Program()
{
Trace.Close();
}
}
Run Code Online (Sandbox Code Playgroud)
我得到文件大小= 0
finilizer 应该执行因为我来自CriticalFinalizerObject
我不想在Finalizer中使用Trace.Close().
@eric利珀特后答复:香港专业教育学院重新编辑的代码,试图把它匹配:约束的执行区域 (但仍然没有成功)
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
class Program : CriticalFinalizerObject
{
static void Main(string[] args)
{
RuntimeHelpers.PrepareConstrainedRegions();
try
{
}
catch (Exception e)
{
}
finally
{
Program p = new Program();
TextWriterTraceListener listener = new TextWriterTraceListener(@"C:\trace1.txt");
Trace.Listeners.Clear();
Trace.Listeners.Add(listener);
Trace.WriteLine("First Trace");
Trace.WriteLine("Perhaps last Trace.");
}
}
~Program()
{
Trace.Flush();
}
}
Run Code Online (Sandbox Code Playgroud)
Eri*_*ert 11
正如文件明确指出:
在从CriticalFinalizerObject类派生的类中,公共语言运行库(CLR)保证所有关键的最终化代码都有机会执行,前提是终结器遵循CER的规则,即使在CLR强制卸载应用程序域的情况下也是如此或中止一个帖子.如果终结器违反了CER的规则,则可能无法成功执行
您的终结器是否遵循约束执行区域的所有规则?
更新:
您已经更新了代码,试图使其遵循约束执行区域的规则,但我没有看到您正确完成的任何证据.规则很清楚; 在受约束的执行区域中的终结器绝对不能执行以下任何操作:
你的终结者会做这五件事吗?如果确实如此,则不要求CLR满足您对终结器始终运行的要求.
此外:暂时忘记约束执行区域,因为现在的程序甚至不是线程安全的.你已经在程序中写了一个讨厌的竞争条件.
在跟踪开始之前,什么阻止了垃圾收集p的抖动?没有!抖动知道p将永远不会再次使用,完全在其分配后立即收集它的权利.冲洗可能会发生在任何时间终结器线程上,包括之前跟踪写入发生,或在任何他们的中间.
Ser*_*kiy 10
因为您没有创建Program类的实例.
你可以在这里阅读更多:
在对象变得不可访问之后自动调用此方法,除非通过调用SuppressFinalize来豁免对象的最终化.在关闭应用程序域期间,会自动调用Finalize,这些对象不会被终止,即使是那些仍然可访问的对象.Finalize在给定实例上仅自动调用一次,除非使用ReRegisterForFinalize和GC等机制重新注册该对象.随后未调用GC.SuppressFinalize.
所以,如果你想要调用finilizer,你需要有对象的实例.
更新:Trace.AutoFlush = true;如果您想要写入消息,请考虑使用.
更新:(为什么不调用Close函数?)实际上你调用了Close函数(如果在其他终结器中没有例外).如果你保持默认的TraceListener(删除Trace.Listeners.Clear()调用),你会看到所有字符串都成功写入Output窗口.
这里的问题是StreamWriter(在TextWriterTraceListener中创建)没有终结器.因此它不会将所有数据刷新到文件.你需要做什么:
FileStream file = new FileStream(@"C:\trace.txt", FileMode.OpenOrCreate);
StreamWriter writer = new StreamWriter(file);
GC.SuppressFinalize(file);
GC.SuppressFinalize(file.SafeFileHandle);
var listener = new TextWriterTraceListener(writer);
Run Code Online (Sandbox Code Playgroud)
实际上,您需要在终结器上手动关闭文件.
| 归档时间: |
|
| 查看次数: |
623 次 |
| 最近记录: |