我有一个后台线程,一旦完成就会更新 UI。我尽量保证安全,以免调用已处置的 GUI。
void DoInBackground()
{
try
{
string result = ServerSideProcess();
* if (!IsDisposed && !Disposing)
* BeginInvoke(new StringDelegate(UpdateText), result);
}
catch (Exception ex)
{
* if (!IsDisposed && !Disposing)
* BeginInvoke(new VoidDelegate(UpdateFailed));
}
}
void UpdateText(string txt)
{
if (!IsDisposed && !Disposing)
textbox1.Text = txt;
}
void UpdateFailed()
{
if (!IsDisposed && !Disposing)
textbox1.Text = "failed to get data from server";
}
override Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
components.Dispose();
}
base.Dispose(disposing);
}
我认为我在 GUI 方法中足够安全 - 当我在 UpdateText(string) 或 UpdateFailed() 中时不会调用 Dispose() 因为它们都在同一个线程中运行,所以我假设检查对于 IsDisposing 和稍后执行就足够了。但是我怎么能确定 (*) 中的部分不会在两者之间获得 Dispose(),这将导致 BeginInvoke 在处理类上被调用,并最终导致应用程序崩溃?
我通过在 (*) 部分之间添加 Thread.Sleep(2000) 来测试它,在 Thread.Sleep 之前和之后放置断点,并移出控制使其在到达 BeginInvoke 之前获得 Dispose()d。结果 - 我的应用程序崩溃了。我怎么知道运行时不会给我这种不幸的上下文切换场景?