Directshow筛选器访问线程

本文关键字:线程 访问 筛选 Directshow | 更新日期: 2023-09-27 17:58:43

我使用directshowlib-2005在c#中制作了一个电视播放器。现在我做了一个方法来搜索可用的频道。

我希望这个方法在不同的线程中运行,这样我的GUI就不会冻结,但当我试图在方法中设置通道时,我会遇到错误。它在我的图中找不到IAMTVTuner接口,尽管我知道它在那里。

如果我不使用不同的线程,该方法工作得很好(但我的GUI会冻结一段时间)

我知道这与公寓有关,但有没有一种方法可以让我在另一个线程中访问该接口,而不是在创建图形的线程中访问?

Directshow筛选器访问线程

这个问题是因为一些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
}