同步被调用(通过分派器)或直接调用的调用

本文关键字:调用 分派 同步 | 更新日期: 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