简体   繁体   English

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

[英]UI button running on separate thread?

my issue is the following:我的问题如下:

1.I have an intensive method which updates GUI element (chart) in a while loop 1.我有一个在while循环中更新GUI元素(图表)的密集方法

2.I need to break out of this loop when a button is pressed. 2.我需要在按下按钮时跳出这个循环。

3.Problem is the button event handler doesn't get executed until the while loop is finished. 3.问题是按钮事件处理程序在while循环完成之前不会执行。

4.I've tried running the method on separate thread but that is very problematic since it sets and reads many UI elements, pretty much I couldn't get that to work, so I'm hoping of there being a way to run just the stop button on a separate thread and update a global variable which let's me break out of the loop. 4.我试过在单独的线程上运行该方法,但这是非常有问题的,因为它设置并读取了许多 UI 元素,几乎我无法让它工作,所以我希望有一种方法可以运行单独线程上的停止按钮并更新一个全局变量,让我跳出循环。

Any Idea how that can be accomplished?任何想法如何实现?

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

In your while loop, you can call Application.DoEvents() .在您的 while 循环中,您可以调用Application.DoEvents() It will fetch UI events from event queue, and process those events.它将从事件队列中获取 UI 事件,并处理这些事件。 Then, your button events will be processed.然后,您的按钮事件将被处理。

You can search by the keyword Application.DoEvents() and C# .您可以通过关键字Application.DoEvents()C# There are many topics about it.有很多关于它的话题。

UPDATE:更新:

In your codes, it is a infinite while loop inside.在您的代码中,它是一个无限的 while 循环。 I don't like to run a infinite in main thread.我不喜欢在主线程中无限运行。 I will prefer to run it in a worker-thread .我更愿意在worker-thread运行它。 And send message to do UI updates in main-thread.并发送消息以在主线程中进行UI更新。 Generally, UI events needs to be processed in the main-thread.通常, UI事件需要在主线程中处理。

If the infinite while loop is already in the worker-thread , it should sleep about 5~10 ms per loop, in order to free CPU resources to process some events in the other threads.如果无限 while 循环已经在worker-thread ,则每个循环应该休眠大约 5~10 毫秒,以释放 CPU 资源来处理其他线程中的某些事件。

You should look at binding your UI element (chart) data to a DependencyProperty .您应该考虑将 UI 元素(图表)数据绑定到DependencyProperty This allows you to run the intensive method on a non-UI thread, allowing your UI thread to be responsive to button clicks.这允许您在非 UI 线程上运行密集方法,允许您的 UI 线程响应按钮点击。 While on the background thread, simply make Dispatcher.BeginInvoke() calls to update your DependencyProperty (as it can only be updated from the UI thread) and this will update your control bound to it.在后台线程上,只需调用Dispatcher.BeginInvoke()来更新您的DependencyProperty (因为它只能从 UI 线程更新),这将更新绑定到它的控件。

As far as your button interrupt goes, a simple solution is to set a flag from your UI which is checked within each loop iteration.就您的按钮中断而言,一个简单的解决方案是从您的 UI 设置一个标志,在每个循环迭代中检查该标志。 A more complex solution would be to run this intensive method in a task Task , giving it CancellationTokenSource , then cancel the source upon button click.更复杂的解决方案是在任务Task运行这种密集型方法,给它CancellationTokenSource ,然后在单击按钮时取消源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM