我有一个后台线程,一旦完成,它就会更新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(),因为它们都在同一线程中运行,所以我假设检查对于IsDispose,以后执行就足够了。但是,我如何确定(*)中的部分之间没有Dispose(),这将导致在处置类上调用BeginInvoke,最终导致应用程序崩溃?

我通过在(*)部分之间添加Thread.Sleep(2000),在Thread.Sleep之前和之后放置断点,并移出控件,使其在到达BeginInvoke之前获取Dispose()d进行了测试。结果-我的应用程序崩溃了。我怎么知道运行时不会给我这种不幸的上下文切换方案?

最佳答案

看来,Backgroundworker已完全免费解决了这个问题。

有什么理由不使用它吗?

10-06 05:14