87266

Task.ContinueWith and DispatcherSynchronizationContext

Question:

I'm facing an issue that I do not understand when unit testing a code that uses task continuation and DispatcherSynchrinizationContext.

My unit test code :

[TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext()); var class1 = new Class1(); var result = class1.MyAsyncMethod().Result; Assert.IsTrue(result == "OK"); } }

The code that is being tested :

class Class1 { public Task<string> MyAsyncMethod() { var tcs = new TaskCompletionSource<string>(); MyInnerAsyncMethod() .ContinueWith(t => { // Never reached if TaskScheduler.FromCurrentSynchronizationContext() is set tcs.SetResult("OK"); }, TaskScheduler.FromCurrentSynchronizationContext()); return tcs.Task; } private Task<string> MyInnerAsyncMethod() { var tcs = new TaskCompletionSource<string>(); tcs.SetResult("OK"); return tcs.Task; } }

The problem is that the code contained within the "ContinueWith" method is never reached <strong>IF</strong> I specify "TaskScheduler.FromCurrentSynchronizationContext()". If I remove this parameter, the continuation executes correctly ...

Any ideas or advices?

Answer1:

I think this is because although you have created a new DispatcherSynchronisationContext, there is no actual thread running a dispatch loop for your task to execute on.

Try putting this at the beginning of your test:

// Create a thread Thread newWindowThread = new Thread(new ThreadStart( () => { // Create our context, and install it: SynchronizationContext.SetSynchronizationContext( new DispatcherSynchronizationContext( Dispatcher.CurrentDispatcher)); // Start the Dispatcher Processing System.Windows.Threading.Dispatcher.Run(); }));

Courtesy of: <a href="http://reedcopsey.com/2011/11/28/launching-a-wpf-window-in-a-separate-thread-part-1/" rel="nofollow">http://reedcopsey.com/2011/11/28/launching-a-wpf-window-in-a-separate-thread-part-1/</a>

Answer2:

<strong>lain</strong> you put me on the right way, thank you !!

I did not modify my code being tested and here is a new implementation of the test code that works as expected :

[TestClass] public class UnitTest1 { private ExecutionContext _executionContext; [TestInitialize] public void OnSetup() { _executionContext = CreateExecutionContext(); SynchronizationContext.SetSynchronizationContext(_executionContext.DispatcherSynchronizationContext); } [TestCleanup] public void OnTearDown() { // stops the dispatcher loop _executionContext.Dispatcher.InvokeShutdown(); } [TestMethod] public void TestMethod1() { var class1 = new Class1(); var result = class1.MyAsyncMethod().Result; Assert.IsTrue(result == "OK"); } /* Helper classes and methods */ private ExecutionContext CreateExecutionContext() { var tcs = new TaskCompletionSource<ExecutionContext>(); var mockUIThread = new Thread(() => { // Create the context, and install it: var dispatcher = Dispatcher.CurrentDispatcher; var syncContext = new DispatcherSynchronizationContext(dispatcher); SynchronizationContext.SetSynchronizationContext(syncContext); tcs.SetResult(new ExecutionContext { DispatcherSynchronizationContext = syncContext, Dispatcher = dispatcher }); // Start the Dispatcher Processing Dispatcher.Run(); }); mockUIThread.SetApartmentState(ApartmentState.STA); mockUIThread.Start(); return tcs.Task.Result; } internal class ExecutionContext { public DispatcherSynchronizationContext DispatcherSynchronizationContext { get; set; } public Dispatcher Dispatcher { get; set; } } /* ------ */ }

Recommend

  • wso2: Can't login to correct publisher tenant
  • Homework: Sublist? checking if an item is a sublist of the first one
  • process is failing in ptrgl_64._ptrgl functionon aix
  • MySQL JOIN by SELECT earliest DATETIME
  • How can I find the id of a gang in OpenACC?
  • Task Parallel Library - how to return immediately but have a parallel step
  • Can to do one query from two queries?
  • Is there any better way to write this query
  • Scraping data from the tag names in python
  • 1:1 Alignment of C# Structs with Streamed Delphi Records Possible?
  • Win Phone 8 / Asp .Net Web API Image Upload
  • How do I scroll HTML textbox to the end?
  • Waiting for responses to asynchronous HTTP requests without async/await
  • Iteration over the dictionary and extracting values
  • Using asynchronous tasks to call synchronous WCF service
  • how to get href link from onclick function in python
  • Making cut/replace methods with JTextArea
  • Task.Factory.StartNew invoked on UI thread anyhow
  • Foreign key constraint error when adding through migrating
  • Excluding some combinations from left join in MySQL
  • Space between buttons and window
  • PHP MYSQL event listener
  • Unable to send more than two input values using a while loop
  • Converting Uint8Array crashing browser for large files
  • vim tabular plugin question
  • Ng-Repeat: Filter By Uniqueness
  • Stopping / Killing Azure Functions Running Instances on Consumption Plan
  • What is Instance Deactivation in WCF?
  • No Buffer Space available(maximum connection reached?) Form Postgres EDB Driver
  • How to check if one div overlapped another during transition from one position to another
  • When is InputStream.available() useful?
  • Dropping support for JRE 1.3
  • Domain name setup with AWS S3 bucket with static hosting
  • how to pass the result model object out of System.Web.Http.ModelBinding.IModelBinder. BindModel?
  • Workflow - Database Design
  • Adding custom controls to a full screen movie
  • How to set the response of a form post action to a iframe source?
  • Change div Background jquery
  • Qt: Run a script BEFORE make
  • reshape alternating columns in less time and using less memory