I'm trying to unit test some behavior in my application that uses Prism's event aggregator. One of the things the code I'm trying to unit test does is subscribe to events on the UI thread. Digging into EventAggregator's implementation, I found that it does so via a SynchronizationContext.Post
.
I thought this answer might be a good workaround, but I ended up using a more simple fix: explicitly setting the sync context at the beginning of the unit test - which works until you attempt to read SynchronizationContext.Current
Which lead me to a behavior I don't entirely understand:
//set the sync context
var thisSyncContext = new SynchronizationContext();
SynchronizationContext.SetSynchronizationContext(thisSyncContext);
thisSyncContext.Post(cb => {
var ctx = SynchronizationContext.Current; //<-- this is null
var equals = thisSyncContext.Equals(ctx); //<-- this is false
},null);
thisSyncContext.Send(cb => {
var ctx = SynchronizationContext.Current; //<-- this is not null
var equals = thisSyncContext.Equals(ctx); //<-- this is true
}, null);
I understand that a Post happens asynchronously and a Send happens synchronously, and when I watch it in the thread debug window, it actually kicks over to a different thread ID, as you would expect an async call to do.
I guess what I'm trying to understand is, when I tell a synchronization context to execute a function, whether synchronously or asynchronously, I would expect that context to be preserved. It is preserved for synchronous calls, but not for async.
Why is this behavior exhibited, and how can I compensate for it in my unit tests?