等待线程完成而无需按住UI线程 [英] Wait for Threads to Finish without holding up UI thread

查看:78
本文介绍了等待线程完成而无需按住UI线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am currently attempting to implement an auto-save feature on test software.

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

The "Start" button fires off TestThread to do testing. The UI is updated via Invokes from TestThread to provide the tester with real time information on the test. When the user clicks the "Stop" button, a flag is set signalling TestThread to finish the current test and stop. It also disables controls on the UI and fires StopThread to monitor TestThread's progress. When TestThread finishes, StopThread re-enables the UI controls.

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

At this point, I need to wait for StopThread to finish so the autosave (SaveFileDialog leading to Excel file generation) can be called. However, using StopThread.Join() in the "Stop" button click handler only seems to cause the program to hang. This is likely because TestThread takes time to finish and attempts to update the blocked UI thread.

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

Calling the save function from StopThread generates a ThreadStateException because I use the SaveFileDialog (modal form) and requires that the calling thread be set to "single thread apartment" apparently.

对此进行搜索似乎指向简单使用Thread.Join()的一般答案.我需要保持UI处于活动状态直到线程完成的简单事实使得此功能无法使用.有没有一种方法可以从StopThread调用SaveFileDialog并将其编组到UI线程?还有其他建议吗?预先感谢.

Searching on this seems to point to general answers on simply using Thread.Join(). The simple fact that I need to keep the UI active until the thread finishes makes this unusable. Is there a way to call the SaveFileDialog from StopThread but marshal it to the UI thread? Any other suggestions? Thanks in advance.

解决方案:

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.
    }

推荐答案

完全不要在StopThread上进行阻止.而是安排StopThread通知主线程它已经完成.例如,使用Invoke.

Don't block on StopThread at all. Instead arrange that StopThread signals the main thread that it has finished. For example by using Invoke.

这篇关于等待线程完成而无需按住UI线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆