InvalidOperationException - object is currently in use elsewhere

claws picture claws · Dec 5, 2009 · Viewed 36.3k times · Source

I've gone through this SO question but it didn't help.

The case here is different. I'm using Backgroundworkers. 1st backgroundworker starts operating on the image input of user and inside firstbackgroundworker_runworkercompleted() I'm using calling 3 other backgroundworkers

 algo1backgroundworker.RunWorkerAsync();
 algo2backgroundworker.RunWorkerAsync();
 algo3backgroundworker.RunWorkerAsync();

this is the code for each:

algo1backgroundworker_DoWork()
{
 Image img = this.picturebox.Image;
 imgclone = img.clone();
 //operate on imgclone and output it
}

algo2backgroundworker_DoWork()
{
 Image img = this.picturebox.Image;
 imgclone = img.clone();
 //operate on imgclone and output it
}

similar operations are done in other algo*backgrougrondworker_doWork().

Now SOMETIMES I'm getting "InvalidOperationException - object is currently in use elsewhere". Its very arbitrary. I somtimes get this in algo1backgroundworker_DoWork and sometimes in algo2backgroundworker_DoWork and sometimes in Application.Run(new myWindowsForm());

I've no clue about whats happening.

Answer

Hans Passant picture Hans Passant · Dec 5, 2009

There's a lock inside GDI+ that prevents two threads from accessing a bitmap at the same time. This is not a blocking kind of lock, it is a "programmer did something wrong, I'll throw an exception" kind of lock. Your threads are bombing because you are cloning the image (== accessing a bitmap) in all threads. Your UI thread is bombing because it is trying to draw the bitmap (== accessing a bitmap) at the same time a thread is cloning it.

You'll need to restrict access to the bitmap to only one thread. Clone the images in the UI thread before you start the BGWs, each BGW needs its own copy of the image. Update the PB's Image property in the RunWorkerCompleted event. You'll lose some concurrency this way but that's unavoidable.