0

So I'm building an UWP app on Windows 10 IoT Core and a Raspberry Pi 3. Now, I want to have a real time clock (without overloading everything) to get an accurate time (received from GPS, but nuw just from the system).

What I did now, was making an Task with infinit while loop in it, to get the time and put it onto a label... But, I can't figure out why the label doesn't get updated in that while loop, yet still it gets updated on page load. The code I'm using can be found below:

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

So the lbl_clock.Text = DateTime.Now.ToString("HH:mm:ss"); works, but never gets updated again and crashes in the while loop, any idea how I can make labels update automatically and in (near) real time?

If I just comment the lbl_clock.Text = DateTime.Now.ToString("HH:mm:ss"); out and debug it (via writing a debug line), it works, what can I do? It's really important for this project.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Robin
  • 1,567
  • 3
  • 25
  • 67

3 Answers3

1

By searching alot more and deeper into code, I found a solution.

So I now do this in the private void:

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

This works like a charm.

Robin
  • 1,567
  • 3
  • 25
  • 67
0

Your problem is try to access a object in other region of memory at the current task. The solution is using "delegates" (sorry of format the response, i write in mobile ...):

    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); 
} 
}); 
}
D3ivid
  • 63
  • 2
0

There is another solution.For executing code and update the property of the element on the UI thread, you also can use MVVM Light framework to resolve this issue.MVVM (Model-View-ViewModel) is and software architectural pattern which provide a clean separation of concerns between the UI controls and their logic. You can refer to this topic.

Michael Xu
  • 4,382
  • 1
  • 8
  • 16