2

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

“开始”按钮触发 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.
    }
4

2 回答 2

3

完全不要阻挡StopThread。而是安排它StopThread向主线程发出它已经完成的信号。例如通过使用Invoke.

于 2012-05-18T14:21:00.523 回答
1

有没有办法从 StopThread 调用 SaveFileDialog 但将其编组到 UI 线程?

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

于 2012-05-18T14:21:15.967 回答