我回答您可以保证using 语句将始终调用Dispose 并且我已纠正,我错了。
using 语句存在潜在的竞争条件,不能保证会被处理,我已经整理了一个控制台应用程序来说明这一点(这并不难或微不足道)。
我在展示 IL 如何生成 using 时是正确的:
var session = new Session(); //If this causes an error or abort happens during initialization then we don't enter try
//If abort is called here then we never enter try
//In either case above we may have undisposed resources initialized at this point
try
{
//do stuff
}
finally
{
session.Dispose();
}
但是;请注意我在输入 try 之前显示中止可能发生的竞争条件的 cmets。
这是一个控制台应用程序,只是为了证明这一点。第一个按预期工作,但如果您在我们初始化 R 时添加注释掉的代码 //thread.Abort(),那么您将看到它初始化但从不处置:/
using System;
using System.Threading;
namespace Question_Answer_Console_App
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Start Main");
Thread thread = null;
thread = new Thread(new ThreadStart(() =>
{
Console.WriteLine("Thread Started");
using (var r = new R(thread))
{
Console.WriteLine($"Using {nameof(R)}");
}
}));
thread.Start();
thread.Join();
Console.WriteLine("End Main");
Console.ReadKey();
}
}
public class R : IDisposable
{
public R(Thread thread)
{
Console.WriteLine($"Init {nameof(R)}");
//thread.Abort();
}
public void Dispose()
{
Console.WriteLine($"Disposed {nameof(R)}");
}
}
}
带有//thread.Abort() 的输出被注释掉:
Start Main
Thread Started
Init R
Using R
Disposed R
End Main
thread.Abort() 的输出未注释掉:
Start Main
Thread Started
Init R
End Main