同步调用(通过调度程序)或直接调用的调用

时间:2011-07-27 12:14:21

标签: c# multithreading

是的,我现在正在为GUI编程。然而,我面临同步问题,我似乎无法自我解决。

我通过UDP远程启动/停止播放视频。传入的代码/命令被解析,然后在'Window'类中执行。

由于它是一个GUI元素,所以任何调用元素的调用都必须在创建它的线程上执行。虽然,我的UDP客户端是在自己的线程上运行的。因此,任何调用都需要通过Dispatcher.Invoke方法。

然而,这工作正常。这有很多问题。例如,'load'方法和'play'方法可以在彼此之后直接执行。这可能导致'play'方法在'load'方法之前执行。因为我无法控制何时在所述对象上调用动作。

所以我想,我会在对象上使用monitor / mutex / semaphore / lock(),然后在再次释放之前等待。请参阅下面的代码段。但这导致了一个例外:

  

通过调用Exit,Pulse,抛出SynchronizationLockException   来自不同步的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);

1 个答案:

答案 0 :(得分:2)

一种可能的方法是让一个线程向另一个线程发出信号,说明他完成了他的工作。因此,您可以使用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