[英]When using dispatcher.BeginInvoke, when/why do I need to call Dispatcher.Run?
[英]How do I avoid a race condition when using Dispatcher.Run()?
我几乎没有找到关于如何正确使用 Dispatcher class 的信息。
目前我正在使用它类似于这个问题,但有一个固有的竞争条件,我在任何地方都没有看到。
假设您使用以下代码启动调度程序线程:
Thread thread = new Thread(Dispatcher.Run);
thread.Start();
并尝试稍后使用它:
Dispatcher.FromThread(thread).Invoke(MyMethodDelegate);
这通常会引发 NullReferenceException,因为 Dispatcher.FromThread 调用可能会返回 null,因为无法保证 Dispatcher.Run 已被调用。
为了正确实现这一点,我所做的是使用信号来确保调度程序正在运行,然后再继续在主线程上使用它。
这是一个较短的版本,作为实用程序 function 完成,受您的启发,所以我省略了评论。
private static Thread CreateDispatcherThread()
{
using (var startedEvent = new ManualResetEventSlim())
{
var dispatcherThread = new Thread( _ => {
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(startedEvent.Set));
Dispatcher.Run(); } );
dispatcherThread.Start();
startedEvent.WaitHandle.WaitOne();
return dispatcherThread;
}
}
这就是我最终要做的事情,我相信您需要这样做才能正确使用 Dispatcher。
private Thread executionThread;
private object SyncObject {get;set;}
private delegate void DispatcherMethod();
private void InitDispatcher()
{
this.SyncObject = new object();
// Set up the dispatcher pump. See Dispatcher.Run on MSDN.
this.executionThread = new Thread(StartDispatcher);
lock (this.SyncObject)
{
this.executionThread.Start();
Monitor.Wait(this.SyncObject);
}
}
private void StartDispatcher()
{
DispatcherMethod method = DispatcherStarted;
// Enqueue a started event by adding an initial method on the message pump.
// Use BeginInvoke because the dispatcher is not actually running yet.
// The call to Dispatcher.CurrentDispatcher handles creating the actual
// Dispatcher instance for the thread (see MSDN - Dispatcher.FromThread
// does not initialize the Dispatcher).
Dispatcher.CurrentDispatcher.BeginInvoke(method);
Dispatcher.Run();
}
private void DispatcherStarted()
{
lock (this.SyncObject)
{
Monitor.Pulse(this.SyncObject);
}
}
InitDispatcher 返回后,可以使用
Dispatcher.FromThread(executionThread).Invoke
或者
Dispatcher.FromThread(executionThread).BeginInvoke
编组对调度程序线程的调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.