多线程实时时钟更新标签

时间:2018-06-16 16:48:03

标签: c# multithreading xaml uwp windows-10-iot-core

所以我正在Windows 10 IoT CoreRaspberry Pi 3上构建一个UWP应用。现在,我希望有一个实时时钟(不会超载所有内容)以获得准确的时间(从GPS接收,但只是来自系统)。

我现在所做的,是在无限循环中创建一个任务,以获取时间并将其放到标签上......但是,我无法弄清楚为什么标签不会更新while循环,但它仍然在页面加载时更新。我正在使用的代码可以在下面找到:

public sealed partial class Tripmaster : Page
{
    public Tripmaster()
    {
        this.InitializeComponent();

        lbl_clock.Text = DateTime.Now.ToString("HH:mm:ss");

        start_clock();

        btn_back.Click += Btn_back_Click;
    }

    private void start_clock()
    {
        // Init the clock and start the thread for the clock.
        Task.Run(() => {
            while (true)
            {
                lbl_clock.Text = DateTime.Now.ToString("HH:mm:ss");
                Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss"));
                Task.Delay(500);
            }
        });
    }

    private void Btn_back_Click(object sender, RoutedEventArgs e)
    {
        this.Frame.Navigate(typeof(MainPage));
    }
}

所以lbl_clock.Text = DateTime.Now.ToString("HH:mm:ss");有效,但永远不会再次更新并在while循环中崩溃,任何想法如何让标签自动更新(近实时)?

如果我只是评论lbl_clock.Text = DateTime.Now.ToString("HH:mm:ss");并调试它(通过编写调试行),它可以工作,我该怎么办?这对这个项目非常重要。

3 个答案:

答案 0 :(得分:1)

通过搜索更多更深入的代码,我找到了解决方案。

所以我现在在私人空白中做到这一点:

private void start_clock()
        {
            // Init the clock and start the thread for the clock.
            Task.Run(async () => {
                while (true)
                {
                    await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                    {
                        this.lbl_clock.Text = DateTime.Now.ToString("HH:mm:ss");
                    });
                    await Task.Delay(500);
                }
            });
        }

这就像一个魅力。

答案 1 :(得分:0)

您的问题是尝试在当前任务中访问其他内存区域中的对象。解决方案是使用"委托" (抱歉格式化回复,我用移动设备写...):

    Private delegate void changuestring (string text);
Private void changuetext (string text)
{
If (lbl_clock.invokerequired)
lbl_clock.invoke(new changuestring(changuetext), text);
Else
lbl_clock.text = text;
}



 private void start_clock()
 { 
// Init the clock and start the thread for the clock. 

Task.Run(() =>
 { 
while (true) 
{ 
changuetext( DateTime.Now.ToString("HH:mm:ss")); Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss")); 
Task.Delay(500); 
} 
}); 
}

答案 2 :(得分:0)

还有另一个解决方案。为了在UI线程上执行代码并更新元素的属性,您还可以使用MVVM Light框架来解决此问题.MVVM(Model-View-ViewModel)是提供的软件架构模式UI控件及其逻辑之间的关注点的清晰分离。您可以参考此topic