InvalidOperationException: object is currently in use elsewhere

G

Guest

When i try to re-use brushes or pens over multiple threads, i often get
an InvalidOperationException with the message 'object is currently in use
elsewhere'.
I also tried this by re-using fonts but no problems there.

So, it looks like brushes and pens cannot be used in different threads
simultaneously.
Looks like a dotnet bug to me.

This exception is easily reproducible with the following code, both on single
and multi processor systems:

Jos Lavrijsen (Philips Medical Systems)


using System;
using System.Drawing;
using System.Drawing.Imaging;

namespace Jos.Test.Problems {

/// <summary>
/// This test shows that brushes cannot be shared over multiple threads
/// Author: Jos Lavrijsen
/// Creation: 26 November 2005
/// </summary>
public class MTDrawProblem {

delegate void Delegate();
static Brush brush = new SolidBrush(Color.Blue);

public static void Start() {
for (int i = 0; i < 100; i++) {
new Delegate(TestIt).BeginInvoke(null, null);
}
}

private static void TestIt() {
try {
Bitmap bitmap = new Bitmap(1024, 1024,
PixelFormat.Format32bppPArgb);
Graphics g = Graphics.FromImage(bitmap);
g.FillRectangle(brush, 0, 0, 1024, 1024);
} catch(InvalidOperationException ex) {
Console.Out.WriteLine(ex);
}
}
}
}
 
L

Larry Lard

Jos said:
When i try to re-use brushes or pens over multiple threads, i often get
an InvalidOperationException with the message 'object is currently in use
elsewhere'.
I also tried this by re-using fonts but no problems there.

So, it looks like brushes and pens cannot be used in different threads
simultaneously.
From the docs (my emphasis):

Brush Class

Thread Safety
Any public static members of this type are thread safe. **Any instance
members are not guaranteed to be thread safe.**
Looks like a dotnet bug to me.

Looks like behaviour as documented to me. Fonts aren't guaranteed
thread-safe either, so you've been lucky so far.
 
J

Jon Skeet [C# MVP]

Jos Lavrijsen said:
When i try to re-use brushes or pens over multiple threads, i often get
an InvalidOperationException with the message 'object is currently in use
elsewhere'.
I also tried this by re-using fonts but no problems there.

So, it looks like brushes and pens cannot be used in different threads
simultaneously.
Looks like a dotnet bug to me.

How can it be a bug when it's the documented behaviour, as Larry
pointed out earlier?

Do you really need to be doing UI operations on multiple threads in the
first place? Usually all UI operations should occur on a single thread.
Given the "Philips Medical Systems" bit, I guess you may be writing a
medical imaging application, in which case it's more likely that it's a
reasonable design, but it's worth checking.
 
G

Guest

Ok, brushes may not be thread safe but it feels strange that an exception
is thrown even though i am not modifying the brush.
Apparently, a brush is not only a description but maybe also contains logic
to perform the actual drawing.

Drawing on bitmaps has nothing to do with UI operations.
In my use-case i am processing a huge amount of images in background to
be exported. To get a high throughput on multiprocessor systems, i use
multiple threads to do this processing.
I try to reuse brushes, fonts and pens to minimize the amount of garbage
produced.

Jos Lavrijsen.
 
J

Jon Skeet [C# MVP]

Jos Lavrijsen said:
Ok, brushes may not be thread safe but it feels strange that an exception
is thrown even though i am not modifying the brush.
Apparently, a brush is not only a description but maybe also contains logic
to perform the actual drawing.

I'd expect so, yes. Whatever the reason, it's a UI element.
Drawing on bitmaps has nothing to do with UI operations.

Well, it is in almost all uses, I'd say. Bitmaps are UI elements as far
as Windows is concerned, so you shouldn't access them (or brushes) on
the wrong thread.
In my use-case i am processing a huge amount of images in background to
be exported. To get a high throughput on multiprocessor systems, i use
multiple threads to do this processing.
I try to reuse brushes, fonts and pens to minimize the amount of garbage
produced.

I suggest you cache them by thread instead. You'll still save a lot of
churn, but without violating the WinForms threading principles.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top