Я пишу код, который вызывается в потоке пользовательского интерфейса, вызывает некоторый код в другом потоке (а не ThreadPool, но тот же поток каждый раз), а затем возобновляется в потоке пользовательского интерфейса. Я бы хотел получить совет по лучшему асинхронному способу сделать это.Продолжая код в другом потоке
Сложность метода EnsureThread заключается в том, что другой поток должен быть одним и тем же потоком каждый раз и должен быть STA с запущенным на нем диспетчером. Это связано с тем, что мне нужно использовать MCI, но не хочу, чтобы он работал в потоке пользовательского интерфейса. См. Здесь https://stackoverflow.com/a/32711239/420159.
Я создаю второй поток, как так:
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;
}
}
}
, а затем я называю второй поток следующим образом:
async void button_click(...)
{
// do something 1
await eventLoopFactory.StartNew(()=>
{
// do something 2
});
// do something 3
}
Есть ли лучший способ сделать это?
Этот метод 'EnsureThread' выглядит очень неудобным для меня. Чего вы пытаетесь достичь? Пока неясно. Пожалуйста, обновите вопрос. – Gusdor
Готово. Короче говоря, я использую mciSendString, для которого требуется поток с циклом событий, но не хочу, чтобы он работал в потоке пользовательского интерфейса, потому что он замедляется из-за пользовательского интерфейса. –