Click here to Skip to main content
14,869,990 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
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:

C#
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:

C#
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??
Posted

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:
C#
[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();
   
Comments
db7uk 30-May-12 5:29am
   
Excellent answer. Indeed this should be looked at.
Pete O'Hanlon 30-May-12 6:33am
   
It's WPF. Right in my comfort zone;)
db7uk 30-May-12 6:36am
   
GC.Collect! PAH! should have known better!
Oleksandr Kulchytskyi 30-May-12 5:46am
   
Yep, you are right, Thanks Pete.
I completly forgot about releasing unmanaged resources.
Now memory consuming increases not so significantly, and releasing memory consumption for resources became much faster.
Pete O'Hanlon 30-May-12 6:41am
   
Easily done. WPF hides so much with it's use of weak patterns that it's easy to forget when you do this.
Pete O'Hanlon 30-May-12 6:43am
   
One other thing. Why not freeze your ImageSource when you create it? It helps to increase performance.
Oleksandr Kulchytskyi 30-May-12 7:05am
   
Oh, one more hint to increase application performance with method Freeze() ;) Thanks, i'll move forward to use that anyway.
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.
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900