title: Async MVVM - how to change NotifyTaskCompletion.Result
body: <p>My question stems from <a href="https://msdn.microsoft.com/en-us/magazine/dn605875.aspx" rel="nofollow">an article</a> of Stephen Cleary.</p>
  
  <p>Basically, there is a Label</p>
  
  <pre><code>&lt;Label Content="{Binding UrlByteCount.Result}"/&gt;
  </code></pre>
  
  <p>and it's set by viewmodel c.tor</p>
  
  <pre><code>UrlByteCount = new NotifyTaskCompletion&lt;int&gt;(
                  MyStaticService.CountBytesInUrlAsync("http://www.example.com"));
  </code></pre>
  
  <p>So far so good.
  Now I do a trivial change:</p>
  
  <pre><code> UrlByteCount = new NotifyTaskCompletion&lt;int&gt;(MyStaticService.ImmediateSet(-1));
  </code></pre>
  
  <p>having defined</p>
  
  <pre><code>public static Task&lt;int&gt; ImmediateSet(int res)
  {
      var tcs = new TaskCompletionSource&lt;int&gt;();
      tcs.SetResult(res);
      return tcs.Task;
  }
  </code></pre>
  
  <p>Obviously the label immediately shows -1.
  Ok, then I add a button with viewmodel command binding, <em>because I want to set the label when I click the button</em>.</p>
  
  <p>skipping all the ceremonial part (delegate command, etc.), the core function is again:</p>
  
  <pre><code>private void TestLogic()
  {
      UrlByteCount = new NotifyTaskCompletion&lt;int&gt;( // FIX ME
          MyStaticService.CountBytesInUrlAsync("http://www.example.com")); // FIX ME
  }
  </code></pre>
  
  <p>I'm perfectly aware that it <em>doesn't</em> work and that the label's content will remain -1, but I'm asking which is the best approach to fix this?</p>
  
  <h1>Second part of the question.</h1>
  
  <p>Assuming you've already found a solution to the first part and the click on the button asynchronously changes the label's content (maintaining ui responsiveness), can you confirm if the following code is a consistent way to prevent "double clicking" (i.e. "multiple executions")?</p>
  
  <pre><code>private async void TestLogic()
  {
      canRun = false;
      ((DelegateCommand)TestCommand).RaiseCanExecuteChanged();
      await FoundASolution();
      canRun = true;
      ((DelegateCommand)TestCommand).RaiseCanExecuteChanged();
  }
  
  private async Task&lt;int&gt; FoundASolution()
  {
      await Task.Delay(TimeSpan.FromSeconds(10));
      return 21;
  }
  </code></pre>