UI 按钮 运行 在单独的线程上?

UI button running on separate thread?

我的问题如下:

1.I 有一个密集的方法,它在 while 循环中更新 GUI 元素(图表)

2.I 需要在按下按钮时跳出此循环。

3.Problem 是按钮事件处理程序在 while 循环完成之前不会执行。

4.I已经在单独的线程上尝试了 运行ning 方法,但这是非常有问题的,因为它设置和读取许多 UI 元素,我几乎无法理解工作,所以我希望有一种方法 运行 只是单独线程上的停止按钮并更新全局变量,让我跳出循环。

知道如何实现吗?

private void playBack(int playTime, int runUntil)
        {
            var frameTime = new DateTime(); var frameTime_ = new DateTime();

            bool fwd = true;
            if (runUntil < playTime) fwd = false;

            playTime = trPlay.Value;

            playGoStop = true;

            lbPlayTime.Text = (playTime * numDtStepSize.Value).ToString();

            while (true) //trPlay.Maximum + 1)
            {
                frameTime = DateTime.UtcNow;
                if ((frameTime - frameTime_).TotalMilliseconds > (double)(1000 / numFps.Value))
                {
                    systemUpdate(playTime);
                    trPlay.Value = playTime;
                    trPlay.Update();

                    lbPlayTime.Update();


                    frameTime_ = frameTime;
                    if (fwd)
                    {
                        playTime++;
                        if (playTime > runUntil) break;
                    }
                    else
                    {
                        playTime--;
                        if (playTime < runUntil) break;
                    }
                }
                if (!playGoStop) break;
            }
        }

您应该考虑将 UI 元素(图表)数据绑定到 DependencyProperty。这允许您在非 UI 线程上 运行 密集方法,允许您的 UI 线程响应按钮点击。在后台线程上,只需调用 Dispatcher.BeginInvoke() 来更新您的 DependencyProperty(因为它只能从 UI 线程更新),这将更新绑定到它的控件。

就您的按钮中断而言,一个简单的解决方案是从您的 UI 设置一个标志,该标志在每次循环迭代中进行检查。更复杂的解决方案是 运行 在任务 Task 中使用这种强化方法,给它 CancellationTokenSource,然后在单击按钮时取消源。

在您的 while 循环中,您可以调用 Application.DoEvents()。它将从事件队列中获取 UI 个事件,并处理这些事件。然后,您的按钮事件将被处理。

您可以通过关键字 Application.DoEvents()C# 进行搜索。关于它的话题很多。

更新:

在你的代码中,它里面是一个无限的while循环。我不喜欢在主线程中 运行 无限。我宁愿运行它在worker-thread。并发送消息在主线程中进行 UI 更新。通常,UI个事件需要在主线程中处理。

如果无限 while 循环已经在 worker-thread 中,它应该在每个循环中休眠 5~10 毫秒,以便释放 CPU 资源来处理其他线程中的一些事件。