1

I want to start long-running operation like requesting a web page from ViewModel, and perform some progress-update operations on my View. Before, I easily achieved this by awaiting my Model's async methods, but in current project I'm restricted with .NET 4.0, so I can't use C#5 features.

What is the recommended way of doing this?

leppie
  • 115,091
  • 17
  • 196
  • 297
astef
  • 8,575
  • 4
  • 56
  • 95

2 Answers2

1

Use this -

Task.Factory.StartNew(() => 
{
   // Code to load web page or any code you want to run asynchronously
}).ContinueWith(task => 
{
   // Code you want to execute on completion of the above synchronous task,
}, UIHelper.GetUITaskScheduler());

wherein the UIHelper class has the following static method -

public class UIHelper
{
   /* Some other methods */

   public static TaskScheduler GetUITaskScheduler()
   {
      TaskScheduler scheduler = null;
      Application.Current.Dispatcher.Invoke(() =>
      {
         scheduler = TaskScheduler.FromCurrentSynchronizationContext();
      });
      return scheduler;
   }    
}
Mayur Dhingra
  • 1,527
  • 10
  • 27
  • In this way I can't update my View's controls. They should be updated from UI's thread and ViewModel must not depend on UI classes – astef Nov 17 '14 at 14:45
  • 1
    You can update the controls if you invoke the update methods via the ui dispatcher – stijn Nov 17 '14 at 14:54
  • I can, but it is dirty way. ViewModel becomes untestable and you have no reason to docouple it from View – astef Nov 17 '14 at 15:00
  • 1
    You can pass in [TaskScheduler.FromCurrentSynchronizationContext()](http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler.fromcurrentsynchronizationcontext%28v=vs.110%29.aspx) to cause the continuation to dispatch to the UI thread (assuming you get the TaskScheduler on the UI thread of course.) – Dan Bryant Nov 17 '14 at 15:43
  • @astef INPC bindings automatically marshall event calls onto the UI thread. Don't believe me? Try it. Alternatively, you can provide a Dispatcher to the ViewModel on which it executes its code. You can provide this in tests. It isn't hard to do. –  Nov 17 '14 at 15:44
  • @astef I agree with you that it should be updated from the UI thread, and as stijn said, you can provide UI thread dispatcher to it for the continouation task. I have updated my answer for it. – Mayur Dhingra Nov 18 '14 at 07:25
0

use RX https://rx.codeplex.com/

You can also observe on the SyncronizationContext.Current

Check them out...

fattikus
  • 542
  • 1
  • 4
  • 15