2

I am new to Windows Phone Dev, and am migrating my WP8 SilverLight app to WP8.1 WinRT. Below is my working code on my ViewModel for WP8 which is not working for the Store app.

Logic behind the code is to update the Xaml txtBox values on UI thread every second which is done inside the UpdateTicker() method.

WP8 Working Code:

        Task.Run(async () =>
        {
            while (true)
            {
                await Task.Delay(1000);
                Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
                {
                    UpdateTicker(); // this method gets called every second
                }), null);
            }
        });

After a lot of search on, MSDN and SO, this where i got to, Below code compile fine for wp8.1 winRT but still does not work - when put a break-point, the debugger reach to the UpdateTicker() step only once, whereas UpdateTicker method should have called every second, (which is what happening for the 1st block of code)

WP8.1 WinRT Code:

        Task.Run(async delegate
        {
            while (true)
            {
                await Task.Delay(1000);
                CoreDispatcher dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
                await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    UpdateTicker();  // this method does not get called every second
                });
            }
        });

Any guidance on using Async Task and Dispatcher.BeginInvoke(Or likewise) together from ViewModel for wp8.1 env is appreciated.

Nishchith Uchil
  • 152
  • 1
  • 14
  • Can you define what "does not work" means? – Daniel Kelley Sep 17 '14 at 12:36
  • The UpdateTicker() is not getting called after every second, as it used to in my 1st block of code under wp8 env. – Nishchith Uchil Sep 17 '14 at 12:50
  • I'm not familiar with WinRT, but it feels like in the second instance you are getting a dispatcher for a background thread. I would imagine `GetForCurrentThread` needs to be called from the UI thread. `Task.Run` will cause your code to be called from a background thread. I may well be wrong. – Daniel Kelley Sep 17 '14 at 13:04
  • Here is another thread on SO, [link](http://stackoverflow.com/questions/9540260/update-ui-from-thread-in-winrt), where they have ried to attain what i want but this one is from code behind, I am looking for somewhat similar but which can be invoked from ViewModel... – Nishchith Uchil Sep 17 '14 at 13:20
  • I saw someone said the pass the dispatcher from the UI thread to the code running in the background thread. I'd try that. – Daniel Kelley Sep 17 '14 at 13:24
  • I tried to follow the comments and other ans on that link - to pass dispatcher thread - but could not get through "Dispatcher.Invoke()", where i am getting error, even when i try it from code behind. For now, @Stephens solution worked for me. However, thanks for quick response. – Nishchith Uchil Sep 17 '14 at 13:53

1 Answers1

9

Actually, I recommend that you avoid Dispatcher, CoreDispatcher, etc. There are always better solutions.

In this case, you can use progress updates. Here's some code that should work on Windows Phone Silverlight 8 as well as Windows Phone Apps 8.1:

IProgress<object> progress = new Progress<object>(_ => UpdateTicker());
Task.Run(async () =>
{
  while (true)
  {
    await Task.Delay(1000);
    progress.Report(null);
  }
});

Side note: In production code, you almost never want to just start a Task.Run and not do anything with the returned Task. At the very least, you should have some code (asynchronously) waiting to catch any exceptions from your loop.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • Hey this one worked for me. Actually, I never happened to come across IProgress class. They seem pretty neat. Also I will consider your recommendation and side note as well. thanks. – Nishchith Uchil Sep 17 '14 at 13:58