【问题标题】:How to shut down a second UI thread如何关闭第二个 UI 线程
【发布时间】:2013-11-06 06:42:19
【问题描述】:

我需要能够在第二个 UI 线程上启动一个窗口并随意再次将其关闭。

这是我当前的代码:

/// <summary>Show or hide the simulation status window on its own thread.</summary>
private void toggleSimulationStatusWindow(bool show)
{
    if (show)
    {
        if (statusMonitorThread != null) return;
        statusMonitorThread = new System.Threading.Thread(delegate()
        {
            Application.Run(new AnalysisStatusWindow(ExcelApi.analyisStatusMonitor));
        });
        statusMonitorThread.Start();
    }
    else
    {
        if (statusMonitorThread != null) 
            statusMonitorThread.Abort();
        statusMonitorThread = null;
    }
}

AnalysisStatusWindow 是一个相当基本的System.Windows.Forms.Form

上面的代码成功创建了新的UI线程,但是我对Abort线程的请求被忽略了。结果是多次切换上述功能只会导致新窗口打开 - 所有这些都在它们自己的线程上并且功能齐全。

有什么方法可以将消息传递给该线程以很好地关闭?如果做不到这一点,有什么方法可以确保 Abort() 真的杀死我的第二个 UI 线程?


我尝试使用new Form().Show().ShowDialog() 代替Application.Run(new Form()),但它们并不容易关闭。

如果有人质疑是否需要单独的 UI 线程,则此代码存在于 Excel 加载项中,并且我无法控制在对给定单元格进行计算时 Excel UI 会阻塞的事实。因此,当执行长时间运行的自定义公式时,我需要第二个 UI 线程来显示进度更新。

【问题讨论】:

  • 您需要公开该表单实例,以便调用其 BeginInvoke() 方法。调用表单类上的公共方法,该方法只调用 this.Close();
  • 谢谢哥们,这正是我需要的主意。

标签: c# multithreading excel


【解决方案1】:

感谢汉斯的评论。我使用以下代码解决了我的问题:

/// <summary>Show or hide the simulation status window on its own thread.</summary>
private void toggleSimulationStatusWindow(bool show)
{
    if (show)
    {
        if (statusMonitorThread != null) return;
        statusMonitorWindow = new AnalysisStatusWindow(ExcelApi.analyisStatusMonitor);
        statusMonitorThread = new System.Threading.Thread(delegate()
        {
            Application.Run(statusMonitorWindow);
        });
        statusMonitorThread.Start();
    }
    else if (statusMonitorThread != null)
    {
        statusMonitorWindow.BeginInvoke((MethodInvoker)delegate { statusMonitorWindow.Close(); });
        statusMonitorThread.Join();
        statusMonitorThread = null;
        statusMonitorWindow = null;
    }
}

【讨论】:

  • 您的BeginInvoke 可以简化为statusMonitorWindow.BeginInvoke((MethodInvoker)statusMonitorWindow.Close);,因为Close() 满足MethodInvoker 签名。
猜你喜欢
  • 1970-01-01
  • 2019-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多