Directshow фильтр доступа потоков

2

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

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

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

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

  • 0
    Какова точная ошибка? Это исключение или какое-то «сообщение о состоянии» из самого приложения?
Теги:
multithreading
com
directshow

1 ответ

1

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

}
  • 1
    @ Герман: ты пробовал это? это решило вашу проблему?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню