我使用 directshowlib-2005 在 c# 中制作了一个电视播放器。 现在我做了一个搜索可用 channel 的方法。
我希望此方法在不同的线程中运行,这样我的 GUI 就不会卡住,但是当我尝试在该方法中设置 channel 时出现错误。它在我的图表中找不到 IAMTVTuner 界面,尽管我知道它在那里。
如果我不使用不同的线程,该方法就可以正常工作(但我的 GUI 会卡住一段时间)
我知道它必须对公寓做一些事情,但有没有一种方法可以让我在另一个线程中访问该接口(interface),然后在创建我的图形的线程中访问该接口(interface)?
最佳答案
这个问题是因为 DirectShowLib
中的某些 com 类或接口(interface)应该只从创建它的同一线程 访问。
所以这个问题的解决方案就是实现ISynchronizeInvoke “System.ComponentModel.ISynchronizeInvoke”。
例如,如果您需要在多线程模式下访问名为 Media
的类中的方法,该类在内部使用 DirectshowLib
中的一些类或方法,则必须检查是否调用使用 InvokeRequired
需要,如果为真,您必须通过 Invoke
方法访问它。
为了演示如何实现 ISynchronizeInvoke
接口(interface),这里摘录了一段我之前在 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
}
关于c# - Directshow 过滤器访问线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6296642/