Да, сейчас я программирую что-то для графического интерфейса. Однако я столкнулся с проблемой синхронизации, которую не могу решить самостоятельно.
Я запускаю/останавливаю воспроизведение видео удаленно через UDP. Входящий код/команда анализируется и затем выполняется в классе «Окно».
Поскольку это элемент GUI, любые вызовы, идущие к элементу, должны выполняться в потоке, из которого он был создан. Хотя мой UDP-клиент запускается в собственном потоке. Таким образом, любые вызовы должны проходить через метод Dispatcher.Invoke.
Однако это работает нормально. Есть несколько проблем с этим. Например, метод «загрузить» и метод «воспроизвести» могут выполняться непосредственно друг за другом. Это может привести к тому, что метод «play» будет выполнен перед методом «load». Потому что я не могу контролировать, когда действие вызывается для указанного объекта.
Поэтому я подумал, что буду использовать монитор/мьютекс/семафор/блокировку() для объекта, а затем буду ждать, пока он снова не будет выпущен. См. ниже фрагменты кода. Но это вызывает исключение:
SynchronizationLockException создается путем вызова методов Exit, Pulse, PulseAll и Wait класса Monitor из несинхронизированного блока кода.
Поэтому я ищу лучший/работающий способ синхронизации обоих потоков. Что, если вызов вызывается через диспетчер, другой поток в основном будет ждать, пока вызываемый метод не завершит вызов.
Кроме того, извините мою формулировку, если я использую неправильные термины.
Способ отправки:
#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);