启动和停止辅助非UI线程

时间:2015-08-25 20:07:38

标签: c# wpf multithreading

我正在重建WPF中的一个WinForms应用程序,我遇到了线程问题。我从我的UI类中的方法启动线程,例如单击按钮:

workerThread = new Thread(() => Engine.Start());
workerThread.Start();

workerThread方法遵循这种通用格式:

static class Engine 
{
    public static bool RunThread = true;
    public static void Start()
    {
        while (RunThread)
        {
            // Do Stuff
        }
    }
}

这是一个不断将数据输出到USB设备的循环。当我从程序中的其他地方将RunThread变量更改为false时,我只希望此线程结束。问题在于等待线程完成。如果我关闭我的MainWindow,线程将继续,直到它尝试启动一个新的循环,然后退出,这意味着它可能会调用MainWindow的部分,因为它被销毁,不再存在。如果我运行workerThread.Join();整个应用程序冻结并变得完全没有响应。

以前,我在我的FormClosing方法中设置了这种类型的东西,以确保它等待线程退出,然后再继续进行其他清理操作:

if (workerThread != null) {
    // Ask the thread to destroy itself
    Engine.RunThread = false;

    // If the thread is busy, wait for it to end
    while (workerThread.IsAlive)
    {
        Application.DoEvents();
        Thread.Sleep(100);
    }
};

这不是最优雅的,但在WinForms中,它确保线程干净利落地然后继续前进。但是,在WPF中尝试类似这样的东西,只会导致它在 while 循环中卡住;因为我认为它阻止线程继续并关闭自己。当然,我必须删除 Application.DoEvents(); ,因为WPF中不存在。

我的怀疑是我没有使用WPF中提供的最佳技术创建这个线程,所以我的问题是:启动此线程的最佳方法是什么,以便我可以安全地退出它(并可能启动一个新实例)以后?

1 个答案:

答案 0 :(得分:1)

正如评论中的其他人所指出的那样,使用Task代替Thread

Task workerTask = Task.Run(() => Engine.Start());

要让UI等待,直到Task完成执行,处理Closing的{​​{1}}事件并等到Window完成。

workerTask