WPF动态图像更改性能问题 [英] WPF dynamical image changing performance issue

查看:56
本文介绍了WPF动态图像更改性能问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好.
您能帮我解决一些WPF性能问题吗?
我有一个WPF应用程序,它具有单个图像,周期性地,比如说每秒一次,我获取了位图图像的字节表示形式,并使用hepl方法显示它,如下所示:

图片来源CretaeFromBytes(字节 [] imgData)
{
使用(MemoryStream ms = newSystem.IO.MemoryStream(imgData))
{
System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
// 将System.Drawing.Image转换为WPF图像
System.Drawing.Bitmap bmp =  System.Drawing.Bitmap(img);
 IntPtr  hBitmap = bmp.GetHbitmap();
ImageSource imageSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr  .0,
Int32Rect.Empty,BitmapSizeOptions.FromEmptyOptions());

返回 imageSource;
}
} 



并在适当的事件处理程序中设置图像:

  void  m_receiver_Received(对象发​​件人,DesktopreceivedEventArgs e)
{
如果(e!= && e.ReceivedData!= 字节 [] uncompress = Common.Extension.Decompress(e.ReceivedData);
//  System.Threading.ThreadPool.QueueUserWorkItem(WriteToFile,解压缩); 
 var  op = Dispatcher.BeginInvoke( Action(
()= > 
{
如果(img1.Source!= 为空&& img1.Source ;

                        ImageSource imageSource = CretaeFromBytes(解压缩);
img1.Source = imageSource;
//  img1.Source = LoadImage(uncompress); 
//  img1.Source = CreateImage(uncompress); 
})
,System.Windows.Threading.DispatcherPriority.Normal);
op.Wait();
}
} 


当我运行我的应用程序时,它开始大量消耗内存.
谁对此有任何建议?

解决方案

在使用GetHBitmap时,当您重新使用该对象时,有责任处置该对象.完成了.为此,您需要使用以下代码:

 [System.Runtime.InteropServices.DllImport(" )]
公共 静态 外部 布尔 DeleteObject(公共 静态  void  Delete(  IntPtr  )
{
  DeleteObject();
} 

然后,当不需要时,只需在hBitmap.Delete();


上调用hBitmap.Delete();

.问题可能归结为垃圾收集器没有时间删除任何不需要的对象.手动调用垃圾收集器GC.Collect每10秒说一次呢?请非常小心,因为这会带来一些性能问题.

我还将在方法调用结束时和GC.Collect之前将uncompress对象设置为null.

我还要考虑将imageSource作为图像要绑定到的属性(MVVM).当图像更改并调用notifyPropertyChanged事件时,这也将有助于体系结构和管理.


Hi guys.
Could you help me with some WPF performance issue?
I have a WPF application with single image, periodically, let say one time in second, i recived a byte representation of bitmap image , and display it with hepl of method, see below:

ImageSource CretaeFromBytes(byte[] imgData)
{
	using (MemoryStream ms = newSystem.IO.MemoryStream(imgData))
	{
		System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
		//convert System.Drawing.Image to WPF image
		System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(img);
		IntPtr hBitmap = bmp.GetHbitmap();
		ImageSource imageSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero,
		Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

		return imageSource;
		}
}



And set image in appropriate event handler:

void m_receiver_Received(object sender, DesktopreceivedEventArgs e)
{
	if (e != null && e.ReceivedData != null)
	{
		byte[] uncompress = Common.Extension.Decompress(e.ReceivedData);
		//System.Threading.ThreadPool.QueueUserWorkItem(WriteToFile, uncompress);
		var op = Dispatcher.BeginInvoke(new Action(
		() =>
		{
			if (img1.Source != null && img1.Source is BitmapSource)
			img1.Source = null;
			
                        ImageSource imageSource=CretaeFromBytes(uncompress);
			img1.Source = imageSource;
			//img1.Source = LoadImage(uncompress);
			//img1.Source = CreateImage(uncompress);
		})
		, System.Windows.Threading.DispatcherPriority.Normal);
		op.Wait();
	}
}


When i run my application it begins significantly consume memory.
Who has any suggestions about it??

解决方案

As you''ve used GetHBitmap, it''s become your responsibility to dispose of the object when you''re finished with it. To do this, you need to use something like this:

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
       
public static void Delete(this IntPtr value)
{
  DeleteObject(value);
}

Then all you need to do on your hBitmap when you don''t need it is call hBitmap.Delete();


an interesting problem. The issue maybe down to the fact the Garbage collector would not have had time to remove any unwanted objects. What about manually calling the garbage collector GC.Collect say every 10 seconds. Be very careful about this as it will impose some performance problems.

I would also set the uncompress object to null at the end of the method call and before the GC.Collect.

I would also think about having the imageSource as a property which your image would bind to (MVVM). When the image changes and the notifyPropertyChanged event is called this should also help with architecture and management.


这篇关于WPF动态图像更改性能问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆