2011-06-09 98 views
2

我使用directshowlib-2005在c#中製作了一個電視播放器。 現在我做了一個搜索可用頻道的方法。DirectShow過濾器訪問線程

我想讓這個方法在不同的線程中運行,所以我的GUI不會凍結,但是當我嘗試在方法中設置通道時出現錯誤。它無法在我的圖表中找到IAMTVTuner接口,儘管我知道它在那裏。

如果我不使用不同的線程,該方法工作得很好(但我的GUI凍結了一會兒)

我知道它是做什麼的公寓,但有什麼辦法,我可以ACCES該接口在不同的線程中,然後線程創建我的圖形?

+0

什麼是** **確切的錯誤?它是來自應用程序本身的異常還是某種「狀態消息」? – Kiril 2011-06-09 19:58:39

回答

1

這個問題是因爲像DirectShowLib中的一些com類或接口應該只是從訪問,它與上創建的線程相同。 所以這個問題的解決方案是實現ISynchronizeInvoke「System.ComponentModel.ISynchronizeInvoke」。

例如,如果你需要訪問一個名爲Media在內部使用從DirectshowLib某些類或方法在多線程模式類的方法,你必須檢查是否需要使用InvokeRequired調用,如果屬實,您必須通過訪問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 

} 
+1

@赫爾曼:你試過這個嗎?它解決了你的問題嗎? – 2011-06-22 18:16:02