我开发了一个有趣的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;
});
}
BackgroundWorker会在后台线程中执行它。看起来很不寻常的是,您也会在单独的线程上(通过ThreadPool)创建BackgroundWorker。这是否有理由? – CodeNaked 2011-06-07 13:16:59
尝试将begininvoke语句注释掉,看看该应用程序是否仍然无响应。如果是,那么它必须是上面没有显示的在GUI线程上运行的代码。后端是否使用任何需要STA的COM互操作? – adrianm 2011-06-07 14:54:20
第三方控件是.NET的winforms控件,但我确信它使用一些COM/GDI技术。 – MickeySixx 2011-06-07 17:49:40