【发布时间】:2015-12-19 02:39:02
【问题描述】:
我正在编写一些在 UI 线程上调用的代码,在另一个线程(不是 ThreadPool,但每次都是同一个线程)上调用一些代码,然后在 UI 线程上恢复。我想要一些关于最好的异步方式的建议。
EnsureThread 方法的复杂性是因为其他线程每次都必须是同一个线程,并且必须是运行 Dispatcher 的 STA。这是因为我需要使用 MCI,但不希望它在 UI 线程上运行。见这里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方法对我来说看起来很可疑。你想达到什么目的?目前还不清楚。请更新问题。 -
完成。简而言之,我正在使用 mciSendString,它需要一个带有事件循环的线程,但不希望它在 UI 线程上运行,因为它会因 UI 而变慢。
标签: c# .net wpf async-await