Directshow фильтр доступа потоков - PullRequest
2 голосов
/ 09 июня 2011

Я сделал TV-Player в c #, используя directshowlib-2005. теперь я сделал метод для поиска доступных каналов.

Я хочу, чтобы этот метод запускался в другом потоке, чтобы мой графический интерфейс не зависал, но я получаю сообщение об ошибке при попытке установить канал в методе. Он не может найти интерфейс IAMTVTuner в моем графике, хотя я знаю, что он там.

Если я не использую другой поток, метод работает нормально (но мой графический интерфейс на некоторое время зависает)

Я знаю, что это как-то связано с квартирами, но есть ли способ, которым я могу получить доступ к этому интерфейсу в другом потоке, отличном от потока, в котором был создан мой график?

1 Ответ

1 голос
/ 19 июня 2011

Эта проблема связана с тем, что некоторые ком-классы или интерфейсы, такие как 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

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...