同步被调用(通过分派器)或直接调用的调用
本文关键字:调用 分派 同步 | 更新日期: 2023-09-27 18:03:34
对,我现在正在为GUI编程。然而,我正面临一个同步问题,我似乎无法自己解决。
我正在通过UDP远程启动/停止视频播放。传入的代码/命令被解析,然后在'Window'类中执行。
因为它是一个GUI元素,任何对元素的调用都必须在创建它的线程上执行。不过,我的UDP客户端在自己的线程上运行。因此,任何调用都需要通过Dispatcher。调用方法。
这是工作良好,然而。这有很多问题。例如,'load'方法和'play'方法可以在彼此之后直接执行。这会导致'play'方法在'load'方法之前执行。因为我无法控制什么时候在该对象上调用操作。
所以我想,我将在对象上使用监视器/互斥锁/信号量/锁(),然后等待它再次释放。请参阅下面的代码片段。但是这会导致一个异常:
SynchronizationLockException通过调用Exit, Pulse,Monitor类的PulseAll和Wait方法从未同步的代码块。
所以我正在寻找一个更好的/工作的方式来同步两个线程。如果调用是通过分派器调用的,其他线程基本上会等待,直到被调用的方法调用完成。
如果我使用了错误的术语,请原谅我的措辞。
调度方法:
#region ExecuteDispatch Members
public void Dispatch(Callback call)
{
Dispatch(this, call);
}
public void Dispatch(DispatcherObject o, Callback call)
{
if (!o.Dispatcher.CheckAccess())
{
o.Dispatcher.Invoke(
System.Windows.Threading.DispatcherPriority.Send,
new Action(call)
);
}
else
{
call();
}
}
#endregion
应该被"同步"的方法:
Monitor.Enter(player);
Dispatch(delegate()
{
player.Stop();
Monitor.Exit(player);
});
Monitor.Enter(player);
Monitor.Exit(player);
一种可能的方法是让一个线程向另一个线程发出完成工作的信号。因此,你可以使用AutoResetEvent或ManualResetEvent:
AutoResetEvent evt = new AutoResetEvent(false);
Dispatch(delegate()
{
player.Stop();
evt.Set();
});
evt.WaitOne(); //Here the thread waits until Set is called on evt