title: updating UWP UI from PPL task continuation - warning C4451
body: <p>I have a sample UWP app with C++ and Visual Studio 2017 Community Edition that I am working to understand the PPL functionality.</p>
  
  <p>I generated a UWP app then made the modifications below to the MainPage.xaml.cpp file. The purpose of these changes is to emulate an asynchronous operation that is taking multiple seconds and to update the displayed UI as the operation completes the various stages.</p>
  
  <p>This works and the UI is updated.</p>
  
  <p>However I do see the following warnings when I compile.</p>
  
  <pre><code>1&gt; ... \appuwp1\mainpage.xaml.cpp(46): warning C4451: 'AppUwp1::MainPage::{ctor}::&lt;lambda_df2e69e2b6fe4b1dfba3f26ad0398a3e&gt;::myThread': Usage of ref class 'Windows::UI::Core::CoreWindow' inside this context can lead to invalid marshaling of object across contexts
  1&gt; ... \appuwp1\mainpage.xaml.cpp(46): note: Consider using 'Platform::Agile&lt;Windows::UI::Core::CoreWindow&gt;' instead
  1&gt; ... \appuwp1\mainpage.xaml.cpp(56): warning C4451: 'AppUwp1::MainPage::{ctor}::&lt;lambda_c1468d2f6468239bd456bea931167a21&gt;::myThread': Usage of ref class 'Windows::UI::Core::CoreWindow' inside this context can lead to invalid marshaling of object across contexts
  1&gt; ... \appuwp1\mainpage.xaml.cpp(56): note: Consider using 'Platform::Agile&lt;Windows::UI::Core::CoreWindow&gt;' instead
  </code></pre>
  
  <p><strong>What do these warnings mean?</strong></p>
  
  <p>I did find this explanation of <a href="https://docs.microsoft.com/en-us/cpp/cppcx/threading-and-marshaling-c-cx" rel="nofollow noreferrer">Threading and Marshaling (C++/CX)</a> which mentions the warning, "Compiler warning when consuming non-agile classes (C4451)" however I am not sure if I have an actual problem or not.</p>
  
  <p><strong>Is there a different, more acceptable way to update the UI from a task continuation?</strong></p>
  
  <p>I am using <code>DispatchedHandler()</code> in order to gain access to the UI thread from the task continuation. If I try to use <code>myTextBlock-&gt;Text = "this is my text and some more text after sleep";</code> without wrapping it in a <code>DispatchedHandler()</code> I get an exception. The exception is understandable since the <code>then</code> task continuation is no longer running in the UI thread.</p>
  
  <p>This stackoverflow, <a href="https://stackoverflow.com/questions/32061672/warning-c4451-usage-of-ref-class-backgroundtaskdeferral-can-lead-to-invalid-mar">Warning C4451: Usage of ref class BackgroundTaskDeferral can lead to invalid marshaling</a> indicates that using <code>Platform:Agile</code> did resolve their warning.</p>
  
  <p>However there is no explanation about what the warning actually means </p>
  
  <p>The initial task creation does nothing other than to start the thread which is handling the asynchronous operation. Each of the <code>then</code> continuation clauses does a <code>Sleep()</code> to represent some action that takes time followed by updating the displayed UI screen with a message.</p>
  
  <pre><code>MainPage::MainPage()
  {
      InitializeComponent();
  
      myTextBlock-&gt;Text = "this is my text and some more text";
      auto myThread = CoreWindow::GetForCurrentThread();
  
      concurrency::create_task ([=]() {
          // we are wanting to spin off a task that will be
          // performed asynchronously and the real work is done in the
          // following task continuations.
          Sleep(5000);
      }).then([=]()
      {
          Sleep(5000);
          myThread-&gt;Dispatcher-&gt;RunAsync(
              CoreDispatcherPriority::Normal,
              ref new DispatchedHandler([=]()
          {
              // Do stuff on the UI Thread
              myTextBlock-&gt;Text = "this is my text and some more text after sleep";
          }));
      }).then([=]()        // warning C4451 for this line
      {
          Sleep(5000);
          myThread-&gt;Dispatcher-&gt;RunAsync(
              CoreDispatcherPriority::Normal,
              ref new DispatchedHandler([=]()
          {
              // Do stuff on the UI Thread
              myTextBlock-&gt;Text = "this is my text and some more text after sleep after sleep again";
          }));
      });             // warning C4451 for this line
  }
  </code></pre>
  
  <p><strong>Additional Exploration #1</strong></p>
  
  <p>With the following changed <code>MainPage::MainPage()</code> I am seeing the expected series of messages displayed in the UI window. Displayed over the course of several seconds are a series of text strings including a series of strings beginning with the incrementing value of <code>iCount</code> generated in the loop in the first task continuation.</p>
  
  <p>It appears that if the <code>for (int iCount = 0; iCount &lt; 3; iCount++) {</code> is placed within the <code>new DispatchedHandler()</code> lambda it causes the UI thread to block for a number of seconds and the UI to become unresponsive and then the text string of the second task continuation is displayed and the UI becomes responsive again. If the <code>for</code> is outside as in this source code sample, the UI thread is not blocked and the UI remains responsive.</p>
  
  <p>Does this mean that the lambda contained within the <code>new DispatchedHandler()</code> is handed over to the UI thread to run?</p>
  
  <pre><code>MainPage::MainPage()
  {
      InitializeComponent();
  
      myTextBlock-&gt;Text = "this is my text and some more text";
      auto myThread = CoreWindow::GetForCurrentThread();
  
      concurrency::create_task ([=]() {
  
          Sleep(2000);
          myThread-&gt;Dispatcher-&gt;RunAsync(
              CoreDispatcherPriority::Normal,
              ref new DispatchedHandler([=]()
          {
              myTextBlock-&gt;Text = "start of task";
  
              // Do stuff on the UI Thread
          }));
      }).then([=]()
      {
          Sleep(5000);
          for (int iCount = 0; iCount &lt; 3; iCount++) {
              myThread-&gt;Dispatcher-&gt;RunAsync(
                  CoreDispatcherPriority::Normal,
                  ref new DispatchedHandler([=]()
                  {
                      // Do stuff on the UI Thread
                      std::wstringstream ss;
  
                      ss &lt;&lt; iCount &lt;&lt; " text first";
                      myTextBlock-&gt;Text = ref new Platform::String(ss.str().c_str());
                  }   )   // close off the DispatchedHandler() lambda
              );          // close off the RunAsync()
              Sleep(2000);
          }               // close off for loop
      }).then([=]()
      {
          Sleep(5000);
          myThread-&gt;Dispatcher-&gt;RunAsync(
              CoreDispatcherPriority::Normal,
              ref new DispatchedHandler([=]()
          {
              // Do stuff on the UI Thread
              myTextBlock-&gt;Text = "this is my text and some more text after sleep after sleep again";
          }));
      });
  }
  </code></pre>
  
  <p><strong>Additional notes</strong></p>
  
  <p><a href="https://www.wintellect.com/mvvm-and-accessing-the-ui-thread-in-windows-store-apps/" rel="nofollow noreferrer">MVVM and Accessing the UI Thread in Windows Store Apps</a></p>
  
  <p><a href="https://eprystupa.wordpress.com/2008/07/28/running-wpf-application-with-multiple-ui-threads/" rel="nofollow noreferrer">Running WPF Application with Multiple UI Threads</a></p>
  
  <p>See also other stackoverflow posts:</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/10579027/run-code-on-ui-thread-in-winrt">Run code on UI thread in WinRT</a></li>
  <li><a href="https://stackoverflow.com/questions/11983929/how-do-i-determine-if-i-need-to-dispatch-to-ui-thread-in-winrt-metro">How do I determine if I need to dispatch to UI thread in WinRT/Metro?</a></li>
  </ul>
  
  <p><a href="https://msdn.microsoft.com/en-us/library/dd504870.aspx" rel="nofollow noreferrer">MSDN article: Concurrency Runtime</a></p>
  
  <p><a href="https://docs.microsoft.com/en-us/cpp/parallel/concrt/task-parallelism-concurrency-runtime" rel="nofollow noreferrer">Task Parallelism (Concurrency Runtime)</a> provides an overview of the concurrency runtime and various options. Several examples and lots of links to additional material.</p>