Я сделал TV-Player в С#, используя directshowlib-2005. теперь я сделал способ поиска доступных каналов.
Я хочу, чтобы этот метод запускался в другом потоке, поэтому мой графический интерфейс не будет зависеть, но я получаю сообщение об ошибке при попытке установить канал в методе. Он не может найти интерфейс IAMTVTuner на моем графике, хотя я знаю его там.
Если я не использую другой поток, метод работает просто отлично (но мой GUI замерзает на некоторое время)
Я знаю, что он должен что-то делать с квартирами, но есть ли способ, которым я могу подключиться к этому интерфейсу в другом потоке, а затем в потоке, где был создан мой график?
Эта проблема связана с тем, что некоторые com-классы или интерфейсы, например, в DirectShowLib
, должны быть доступны только из того же потока, который был создан на.
Таким образом, решение этой проблемы заключается в реализации ISynchronizeInvoke "System.ComponentModel.ISynchronizeInvoke".
Например, если вам нужно получить доступ к методам в классе с именем Media
, который использует внутри себя несколько классов или методов из DirectShowLib
в режиме многопоточности, вам нужно проверить, требуется ли использование вызова с помощью InvokeRequired
, и если true должны получить доступ к нему с помощью метода Invoke
.
Чтобы продемонстрировать, как реализовать интерфейс ISynchronizeInvoke
, здесь приведен фрагмент кода, который я разработал некоторое время назад в С# 2.0
public abstract class Media : ISynchronizeInvoke
{
//....
private readonly System.Threading.SynchronizationContext _currentContext = System.Threading.SynchronizationContext.Current;
private readonly System.Threading.Thread _mainThread = System.Threading.Thread.CurrentThread;
private readonly object _invokeLocker = new object();
//....
#region ISynchronizeInvoke Members
public bool InvokeRequired
{
get
{
return System.Threading.Thread.CurrentThread.ManagedThreadId != this._mainThread.ManagedThreadId;
}
}
/// <summary>
/// This method is not supported!
/// </summary>
/// <param name="method"></param>
/// <param name="args"></param>
/// <returns></returns>
[Obsolete("This method is not supported!", true)]
public IAsyncResult BeginInvoke(Delegate method, object[] args)
{
throw new NotSupportedException("The method or operation is not implemented.");
}
/// <summary>
/// This method is not supported!
/// </summary>
/// <param name="method"></param>
/// <param name="args"></param>
/// <returns></returns>
[Obsolete("This method is not supported!", true)]
public object EndInvoke(IAsyncResult result)
{
throw new NotSupportedException("The method or operation is not implemented.");
}
public object Invoke(Delegate method, object[] args)
{
if (method == null)
{
throw new ArgumentNullException("method");
}
lock (_invokeLocker)
{
object objectToGet = null;
SendOrPostCallback invoker = new SendOrPostCallback(
delegate(object data)
{
objectToGet = method.DynamicInvoke(args);
});
_currentContext.Send(new SendOrPostCallback(invoker), method.Target);
return objectToGet;
}
}
public object Invoke(Delegate method)
{
return Invoke(method, null);
}
#endregion//ISynchronizeInvoke Members
}