Моя цель — синхронно запускать этот код во время тестов.
Возможно ли это?
Я пробовал с «синхронным» SynchronizationContext:
Код: Выделить всё
public class SynchronousSynchronizationContext : SynchronizationContext
{
private readonly ConcurrentQueue _workItems = new ConcurrentQueue();
private readonly AutoResetEvent _workItemsAvailable = new AutoResetEvent(false);
public override void Post(SendOrPostCallback d, object state)
{
Trace.WriteLine("SynchronousSynchronizationContext.Post(), start");
// Execute the callback immediately
d(state);
Trace.WriteLine("SynchronousSynchronizationContext.Post(), end");
}
/* enqueues the work item to be completed later:
public override void Post(SendOrPostCallback d, object state)
{
Trace.WriteLine("SynchronousSynchronizationContext.Post()");
_workItems.Enqueue((d, state));
_workItemsAvailable.Set();
}
*/
public override void Send(SendOrPostCallback d, object state)
{
Trace.WriteLine("SynchronousSynchronizationContext.Send()");
d(state);
}
public void Run()
{
Trace.WriteLine("SynchronousSynchronizationContext.Run()");
while (_workItems.TryDequeue(out var workItem))
{
workItem.Item1(workItem.Item2);
}
}
public void Complete()
{
Trace.WriteLine("SynchronousSynchronizationContext.Complete()");
while (_workItems.TryDequeue(out var workItem))
{
Trace.WriteLine("SynchronousSynchronizationContext, execute callback");
// execute callback.
// The workItem is a tuple where Item1 is the callback and Item2 is the state object.
workItem.Item1(workItem.Item2);
}
}
}
Вместо этого мне приходится явно вызывать Complete() в различных точках моего тестового метода:
Код: Выделить всё
private SynchronousSynchronizationContext _syncContext;
[TestInitialize]
public void TestInitialize()
{
_syncContext = new SynchronousSynchronizationContext();
SynchronizationContext.SetSynchronizationContext(_syncContext);
}
[TestMethod]
public void MyTest_ReturnsData()
{
// ACT
MyTest();
// Finish all fire-and-forget tasks:
_syncContext.Complete();
// ASSERT
...
}