Directshow筛选器访问线程
本文关键字:线程 访问 筛选 Directshow | 更新日期: 2023-09-27 17:58:43
我使用directshowlib-2005在c#中制作了一个电视播放器。现在我做了一个方法来搜索可用的频道。
我希望这个方法在不同的线程中运行,这样我的GUI就不会冻结,但当我试图在方法中设置通道时,我会遇到错误。它在我的图中找不到IAMTVTuner接口,尽管我知道它在那里。
如果我不使用不同的线程,该方法工作得很好(但我的GUI会冻结一段时间)
我知道这与公寓有关,但有没有一种方法可以让我在另一个线程中访问该接口,而不是在创建图形的线程中访问?
这个问题是因为一些com类或接口(如DirectShowLib
中)应该只从上创建的同一线程访问。因此,解决这个问题的方法是实现ISynchronizeInvoke"System.ComponentModel.ISynchronizeInvoke."
例如,如果您需要访问名为Media
的类中的方法,该类在多线程模式下在内部使用DirectshowLib
中的某些类或方法,则必须检查是否需要使用InvokeRequired
进行调用,如果为true,则必须通过Invoke
方法进行访问。为了演示如何实现ISynchronizeInvoke
接口,这里有一个我不久前在C#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
}