I'm writing some code that is invoked on the UI thread, invokes some code on another thread (not the ThreadPool, but the same thread each time), and then resumes on the UI thread. I'd like some advice on the best async way to do this.
The complexity of the EnsureThread method is because the other thread must be the same thread every time and must be STA with a Dispatcher running on it. This is because I need to use MCI, but do not want it running on the UI thread. See here https://stackoverflow.com/a/32711239/420159.
I create the second thread like so:
private static void EnsureThread()
{
if (eventLoopThread != null)
{
return;
}
lock (eventLoopLock)
{
if (eventLoopThread == null)
{
var lck = new EventWaitHandle(false, EventResetMode.ManualReset);
var t = new Thread(() =>
{
try
{
// create dispatcher and sync context
var d = Dispatcher.CurrentDispatcher;
var context = new DispatcherSynchronizationContext(d);
SynchronizationContext.SetSynchronizationContext(context);
// create taskfactory
eventLoopFactory = new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());
eventLoopDispatcher = d;
}
finally
{
lck.Set();
}
// run the event loop
Dispatcher.Run();
});
t.SetApartmentState(ApartmentState.STA);
t.IsBackground = true;
t.Start();
lck.WaitOne();
lck.Dispose();
eventLoopThread = t;
}
}
}
and then I call the second thread like so:
async void button_click(...)
{
// do something 1
await eventLoopFactory.StartNew(()=>
{
// do something 2
});
// do something 3
}
Is there a better way to do it?