Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Processing Bitmap object asynchronously with c#

What I'm trying to process a bitmap object in several threads. I create the object in UI thread and want to save it asynchronously. After save method is called, I continue to process the bitmap and manipulate it in several ways.

When the main thread modifies the bitmap, async thread throws an error or corrupts the stream. I tried to use async/await and ThreadStart implementations, both results are same.

I've been able to fix this by copying bitmap stream and send the new stream to async method but this has a performance penalty. Copying it almost takes the half time of the saving it, especially when working with large streams.

I wondered if anybody have a workaround for this scenario.

like image 885
Kerem Demirer Avatar asked Mar 16 '26 12:03

Kerem Demirer


2 Answers

I'll assume this question is about the System.Drawing.Bitmap class. Almost any non-trivial operation on the bitmap calls the equivalent of Bitmap.LockBits() under the hood. This includes Image.Save(), Graphics.FromImage(), Bitmap.SetPixel() etcetera. This lock can be held by only one thread at a time. Any other thread that tries to lock the bitmap will trigger the exception.

It is therefore entirely up to you to ensure that no two threads can access the bitmap at the same time. In other words, you must use the lock keyword in your code to ensure that a thread is blocked when the bitmap is in use. Do note the inevitable loss of concurrency you'll get from this, your UI thread will be stalled while your worker thread tinkers with the bitmap if it happens to want to paint the bitmap at the same time.

Do beware that this is not always possible. You for example cannot alter the PictureBox class to insert the required lock. Same story for the BackgroundImage property. Etcetera. With the consequence that you cannot use these convenience classes/properties anymore, you have to take care of painting yourself so you can insert the lock.

like image 54
Hans Passant Avatar answered Mar 18 '26 00:03

Hans Passant


You can use the Parallel class in System.Threading.Tasks namespace. Following link has some samples and explanations.

  • http://csharpexamples.com/fast-image-processing-c/
  • http://msdn.microsoft.com/en-us/library/dd460713%28v=vs.110%29.aspx
like image 44
turgay Avatar answered Mar 18 '26 00:03

turgay