title: Why doesn't TaskScheduler.FromCurrentSynchronizationContext synchronize in Monotouch?
body: <p>The thing i am interested in is why do we need to call InvokeOnMainThread while this would be the main intent and responsibility of TaskScheduler.FromCurrentSynchronizationContext()?.</p>
  
  <p>I am using the TPL in Monotouch for an iPhone app to do some background tasks and update the UI via a reporter class. But it seems that TaskScheduler.FromCurrentSynchronizationContext() is not synchronizing to the UI thread as what you would expect. At this time I managed to get it working (but still feels wrong) by using InvokeOnMainThread as described by the <a href="http://docs.xamarin.com/ios/advanced_topics/threading" rel="nofollow noreferrer">Threading</a> topic at Xamarin's site. </p>
  
  <p>I also found a reported (similar) <a href="https://bugzilla.novell.com/show_bug.cgi?id=690944" rel="nofollow noreferrer">bug</a> at BugZilla that seems to be resolved.. and another <a href="https://stackoverflow.com/questions/8088502/monotouch-threading">threading question</a> about the preferred way of using background threads in MonoTouch.</p>
  
  <p>Below is the code snippet to illustrate my question and to show the behaviour. </p>
  
  <pre><code>    private CancellationTokenSource cancellationTokenSource;
  
      private void StartBackgroundTask ()
      {
          this.cancellationTokenSource = new CancellationTokenSource ();
          var cancellationToken = this.cancellationTokenSource.Token;
          var progressReporter = new ProgressReporter ();
  
          int n = 100;
          var uiThreadId = Thread.CurrentThread.ManagedThreadId;
          Console.WriteLine ("Start in thread " + uiThreadId);
  
          var task = Task.Factory.StartNew (() =&gt;
          {
              for (int i = 0; i != n; ++i) {
  
                  Console.WriteLine ("Work in thread " + Thread.CurrentThread.ManagedThreadId);
  
                  Thread.Sleep (30); 
  
                  progressReporter.ReportProgress (() =&gt;
                  {
                      Console.WriteLine ("Reporting in thread {0} (should be {1})",
                          Thread.CurrentThread.ManagedThreadId,
                          uiThreadId);
  
                      this.progressBar.Progress = (float)(i + 1) / n;
                      this.progressLabel.Text = this.progressBar.Progress.ToString();
  
                  });
              }
  
              return 42; // Just a mock result
          }, cancellationToken);
  
          progressReporter.RegisterContinuation (task, () =&gt;
          {
              Console.WriteLine ("Result in thread {0} (should be {1})",
                  Thread.CurrentThread.ManagedThreadId,
                  uiThreadId);
  
              this.progressBar.Progress = (float)1;
              this.progressLabel.Text = string.Empty;
  
              Util.DisplayMessage ("Result","Background task result: " + task.Result);
  
          });
      }
  </code></pre>
  
  <p>And the reporter class has these methods</p>
  
  <pre><code>    public void ReportProgress(Action action)
      {
          this.ReportProgressAsync(action).Wait();
      }
      public Task ReportProgressAsync(Action action)
      {
          return Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
      }
      public Task RegisterContinuation(Task task, Action action)
      {
          return task.ContinueWith(() =&gt; action(), CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
      }
      public Task RegisterContinuation&lt;TResult&gt;(Task&lt;TResult&gt; task, Action action)
      {
          return task.ContinueWith(() =&gt; action(), CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
      }
  </code></pre>
  
  <p>The results in the Application output window will be:</p>
  
  <pre><code>Start in thread 1
  Work in thread 6
  Reporting in thread 6 (should be 1)
  Work in thread 6
  Reporting in thread 6 (should be 1)
  ...
  Result in thread 1 (should be 1)
  </code></pre>
  
  <p>As you can see 'Work in thread 6' is fine. Reporting is also on thread 6, this is wrong. The funny part is that the <code>RegisterContinuation</code> does its reporting in thread 1!!! </p>
  
  <hr>
  
  <p>PROGRESS: I still haven't figured this one out.. Anyone?</p>