等待线程完成而不保留 UI 线程

本文关键字:线程 保留 UI 等待 | 更新日期: 2023-09-27 18:34:47

我目前正在尝试在测试软件上实现自动保存功能。

"开始"按钮触发TestThread进行测试。 UI 通过 TestThread 的调用进行更新,以便为测试人员提供有关测试的实时信息。 当用户单击"停止"按钮时,会设置一个标志,指示 TestThread 完成当前测试并停止。 它还禁用 UI 上的控件并触发 StopThread 来监视 TestThread 的进度。 TestThread 完成后,StopThread 将重新启用 UI 控件。

此时,我需要等待 StopThread 完成,以便可以调用自动保存(导致 Excel 文件生成的 SaveFileDialog(。 但是,在"停止"按钮单击处理程序中使用 StopThread.Join(( 似乎只会导致程序挂起。 这可能是因为 TestThread 需要一些时间才能完成并尝试更新被阻止的 UI 线程。

从 StopThread 调用 save 函数会生成一个 ThreadStateException,因为我使用 SaveFileDialog(模态形式(,并且显然要求将调用线程设置为"单线程单元"。

对此进行搜索似乎指向仅使用 Thread.Join(( 的一般答案。 我需要在线程完成之前保持 UI 处于活动状态的简单事实使其无法使用。 有没有办法从 StopThread 调用 SaveFileDialog,但将其封送到 UI 线程? 还有其他建议吗? 提前谢谢。

工作解决方案:

private void btn_Stop_Click(object sender, EventArgs e)
    {
        //Disable UI controls and flag test ending
        Thread StopThread = new Thread(WaitForTestEnd);
        StopThread.Start();        
    }
    private void WaitForTestEnd()
    {
        while (!testStopped) //Flag set at end of TestThread
        {
            Thread.Sleep(50);
        }
        //Re-enable UI
        AutoSave saveMyData = SaveData;
        Invoke(saveMyData);
    }
    private delegate void AutoSave();
    private void SaveData()
    {
        //Generate SaveFileDialog and save.
    }

等待线程完成而不保留 UI 线程

根本不会阻止StopThread。相反,安排StopThread表示主线程已完成的信号。例如,通过使用 Invoke .

有没有办法从 StopThread 调用 SaveFileDialog,但将其封送到 UI 线程?

你为什么不直接使用 Control.InvokeDispatcher.Invoke ,就像听起来像你来自 TestThread 一样?