2011-06-07 53 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。 应用程序空闲表示当应用程序空闲时处理操作。

如果应用程序总是很忙而且从不闲置呢?这些请求将排队等待,并且应用程序变慢。

但是我没有测试过这个,因为我没有你的应用程序的源代码。