2011-06-07 54 views
1

我開發了一個有趣的WPF控件,目前正在減慢我的整個應用程序:)在我的自定義控件上,我有一個圖像控件,每次發生後端事件時都需要更新。這個後端事件每秒發射兩次(非常快)。當事件觸發時,我需要從第三方控件中取出Bitmap對象,轉換爲BitmapSource對象,然後將其綁定到我的Image控件。每次我的事件被解僱時,我都會在ThreadPool中排隊一個新的工作項目。該項目將獲取位圖並在後臺工作對象中執行轉換。每當事件發生時都會執行此操作。我使用調度程序來更新我的圖像控制源與BeginInvoke,但我仍然得到一個沒有反應的應用程序。請讓我知道我能做些什麼來使這個過程更高性能和幫助,使我的應用程序更加敏感:WPF Threading Grab Bag

這裏是我的事件代碼:

void inSight_ResultsChanged(object sender, EventArgs e) 
     { 

      ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessEvent), ((InSightViewer)this.DataContext).CvsDisplay); 
     } 

下面是從委託代碼:

void ProcessEvent(object display) 
     { 
      BackgroundWorker bw = new BackgroundWorker(); 
      bw.DoWork += new DoWorkEventHandler(bw_DoWork); 
      bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); 
      bw.RunWorkerAsync(display); 

     } 

這裏是我的後臺工作的DoWork事件的代碼:

void bw_DoWork(object sender, DoWorkEventArgs e) 
     { 
      3rdPartyControl displayControl = new 3rdPartyControl(); 

      displayControl.ImageHost = (ImgHost)e.Argument; 


      Bitmap b = displayControl.GetBitmap(); 

      var mBitmap = b.GetHbitmap(); 
      BitmapSource bs; 

      try 
      { 
       bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
          mBitmap, 
          IntPtr.Zero, 
          Int32Rect.Empty, 
          BitmapSizeOptions.FromEmptyOptions()); 

       bs.Freeze(); 
      } 
      catch (System.Exception ex) { throw ex; } 
      finally 
      { 
       DeleteObject(mBitmap); 
      } 

      e.Result = bs; 
     } 

這裏是RunWorkerCompleted事件的代碼:

void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.ApplicationIdle, (ThreadStart)delegate() 
     { 
      this.imgSource.Source = (BitmapSource)e.Result; 
     }); 
} 
+3

BackgroundWorker會在後臺線程中執行它。看起來很不尋常的是,您也會在單獨的線程上(通過ThreadPool)創建BackgroundWorker。這是否有理由? – CodeNaked 2011-06-07 13:16:59

+0

嘗試將begininvoke語句註釋掉,看看該應用程序是否仍然無響應。如果是,那麼它必須是上面沒有顯示的在GUI線程上運行的代碼。後端是否使用任何需要STA的COM互操作? – adrianm 2011-06-07 14:54:20

+0

第三方控件是.NET的winforms控件,但我確信它使用一些COM/GDI技術。 – MickeySixx 2011-06-07 17:49:40

回答

0
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
     Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.ApplicationIdle, (ThreadStart)delegate() 
     { 
      this.imgSource.Source = (BitmapSource)e.Result; 
     }); 
} 

System.Windows.Threading.DispatcherPriority。 應用程序空閒表示當應用程序空閒時處理操作。

如果應用程序總是很忙而且從不閒置呢?這些請求將排隊等待,並且應用程序變慢。

但是我沒有測試過這個,因爲我沒有你的應用程序的源代碼。