持续更新 UI 的正确方法 [英] Right way to continuously update the UI

查看:26
本文介绍了持续更新 UI 的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设客户端应用几乎实时地从服务器获取数据.根据检索到的数据持续更新 UI 的更有效方法是什么.考虑多个 xaml 控件,例如显示数字的文本.只要应用程序在运行,这些就会更新.除非用户决定,否则他们永远不会停止.(假设按停止按钮或退出应用程序)下面我有一个使用 async 和 await 关键字的简单示例.这是我的场景的好方法吗?或者例如 BackgroundWorker 会是更好的方法?

Assuming that a client app gets data from a server nearly in real time. What is the more efficient way to continuously update the UI based on the retrieved data. Think of multiple xaml controls, like texts that show numbers. Those get updated as long as the application is running. They never stop unless the user decides it. (let's say by pressing a stop button or exit the app) Below I have a simple example utilizing async and await keywords. Is that a good way for my scenario? Or for example BackgroundWorker would be a better way?

private async void Button_Click_Begin_RT_Update(object sender, RoutedEventArgs e)
{
    while(true)
        textField1.Text = await DoWork();
}

Task<string> DoWork()
{
    return Task.Run(() =>
    {
        return GetRandomNumberAsString();
    });
}

*为了简单起见,我在示例中使用代码隐藏而不是 mvvm

*for the sake of simplicity I use code-behind and not mvvm in my example

推荐答案

如果您的 GetRandomNumberAsString() 至少需要 15 毫秒才能完成,那么您的代码或多或少是可以的.

Your code is more or less OK if your GetRandomNumberAsString() takes at least 15ms to complete.

如果它花费的时间少于这个,并且您想最大限度地减少更新延迟,即您不想只是等待,您可能需要 (1) 将您的每个操作 Task.Run 替换为完全在后台线程中运行的无限循环 (2) 在该循环中实现节流机制,并且仅在 30-60Hz 左右更新您的 GUI(例如使用 Dispatcher.BeginInvoke()).

If it takes less than that, and you want to minimize update latency i.e. you don't want to just wait, you might want to (1) replace your per-operation Task.Run with an endless loop that completely runs in a background thread (2) Implement throttling mechanism in that loop, and only update your GUI (using e.g. Dispatcher.BeginInvoke()) at around 30-60Hz.

附言您更新 GUI 的确切机制(数据绑定 + INotifyPropertyChanged,或直接在您的代码中)与性能无关.

P.S. The exact mechanism how you update your GUI (databinding + INotifyPropertyChanged, or directly like in your code) is not relevant for performance.

更新:这是示例(未经测试)

Update: here's example (untested)

static readonly TimeSpan updateFrequency = TimeSpan.FromMilliseconds( 20 );
void ThreadProc()
{
    Stopwatch sw = Stopwatch.StartNew();
    while( true )
    {
        string val = GetRandomNumberAsString();
        if( sw.Elapsed < updateFrequency )
            continue;   // Too early to update
        sw.Restart();
        Application.Current.Dispatcher.BeginInvoke( () => { textField1.Text = val; } );
    }
}

这篇关于持续更新 UI 的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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