我目前正在尝试在测试软件上实现自动保存功能。
“开始”按钮会触发TestThread进行测试。 UI通过TestThread的Invokes更新,为测试人员提供测试的实时信息。当用户单击“停止”按钮时,会设置一个标志,指示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.
}
答案 0 :(得分:3)
根本不要阻止StopThread
。而是安排StopThread
表示它已完成的主线程。例如,使用Invoke
。
答案 1 :(得分:1)
有没有办法从StopThread调用SaveFileDialog但是将其封送到UI线程?
为什么不使用Control.Invoke
或Dispatcher.Invoke
,就像听起来像来自TestThread一样?