"object is currently in use elsewhere" - I'm stumped

S

stevek

I've run out of ideas on how to find this bug I've got. I've read up on the
topic and understand that this most likely has something to do with a
threading bug but I can't find it and any attempts to recreate the problem
in a simple and complete application have failed. I've logged the Managed
Thread ID everywhere that I can think of that could be causing the problem
and the IDs are all the same.

"Object is currently in use elsewhere" - what object? From the stacktrace
in my exception it looks like it's definitly the Image instance but I'm not
*positive*.

I know that I should post a working code sample in order to expect any kind
of useful response from the list, but as I mentioned earlier I can't
reproduce in a simple application. I've analyzed the differences between my
real world application and the sample and nothing has stuck out as a clue or
cause. The only thing I can do at this point is explain what my application
is doing as best as I can and include the stack trace.

I would also like to invite anyone that is confident they can identify this
problem via a webex and phone session to contact me. I'd love to pay
someone for an hour of time (or more) to take a look and help me find this
bug.

OK, so I will now try to explain the situation.

**I'm using the Composite Application Block framework for this application.

1. User makes shipping label request by clicking a button on the View (MVP)
2. The Presenter requests an Image from a singleton service method (this
method receives base64 encoded image data and constructs an Image instance
and returns)
3. The singleton service method does some post-processing operations on the
image (removing borders, etc)
4. The presenter then calls a print method on another Singleton object which
prints the image.


Here is the stacktrace:
System.InvalidOperationException: Object is currently in use elsewhere.
at System.Drawing.Image.get_RawFormat()
at System.Drawing.Graphics.IgnoreMetafileErrors(Image image, Int32&
errorStatus)
at System.Drawing.Graphics.DrawImage(Image image, Int32 x, Int32 y, Int32
width, Int32 height)
at PMD.Services.PrintingService.document_PrintPage(Object sender,
PrintPageEventArgs e) in C:\PrintingService.cs:line 48
at System.Drawing.Printing.PrintDocument.OnPrintPage(PrintPageEventArgs
e)
at System.Drawing.Printing.PrintDocument._OnPrintPage(PrintPageEventArgs
e)
at System.Drawing.Printing.PrintController.PrintLoop(PrintDocument
document)
at System.Drawing.Printing.PrintController.Print(PrintDocument document)
at System.Drawing.Printing.PrintDocument.Print()
at PMD.Services.PrintingService.Print(Image image, String documentName,
String printerName) in C:\PrintingService.cs:line 39
at PMD.ProcessReturnShipmentViewPresenter.Finished() in
C:\ProcessReturnShipmentViewPresenter.cs:line 111

My drawing code is all wrapped in using blocks like so:
private Image PostProcessLabelImage(Image image)
{
// Creating a new copy to try and work around the
// object already in use bug
Image newCopy = new Bitmap(image.Width, image.Height);

// TODO: move this out to the constructor
Rectangle croppedRec = new Rectangle(2, 2, newCopy.Width-4,
newCopy.Height-4);

using (Graphics g = Graphics.FromImage(newCopy))
{
// There is a black border that we want to remove. Paint the
// image to the new DC minus the 2 pixel border
g.DrawImage(image, croppedRec, croppedRec, GraphicsUnit.Pixel);

// Cover up the endicia logo - BS that they even do that,
// should be OUR logo if anything!
g.FillRectangle(Brushes.White, image.Width - 65, 90,
image.Width - 55, 270);
}

return newCopy;
}

Again, guys, I know this bugs you when someone doesn't post a complete
sample. I really have tried to come up with one but haven't been able to.
If you are interested in the gotomeeting approach please contact me ( sklett
[at] pmd direct com ) I can fire up the debugger and step through the code.

-Steve
 
M

Morten Wennevik [C# MVP]

Hi Steve,

According to this article this error may be caused by a DC object not
properly released, so the DC object is used elsewhere, or not properly
released.

http://msmvps.com/blogs/peterritchi...is-currently-in-use-elsewhere-quot-error.aspx

I don't see a direct use of DC objects in your code, but the Graphics object
is basically a wrapper around the DC and the stacktrace indicate the Graphics
object. Maybe you get this error if you try to create two different Graphics
objects from the same Image before you release either one.

--
Happy Coding!
Morten Wennevik [C# MVP]


stevek said:
I've run out of ideas on how to find this bug I've got. I've read up on the
topic and understand that this most likely has something to do with a
threading bug but I can't find it and any attempts to recreate the problem
in a simple and complete application have failed. I've logged the Managed
Thread ID everywhere that I can think of that could be causing the problem
and the IDs are all the same.

"Object is currently in use elsewhere" - what object? From the stacktrace
in my exception it looks like it's definitly the Image instance but I'm not
*positive*.

I know that I should post a working code sample in order to expect any kind
of useful response from the list, but as I mentioned earlier I can't
reproduce in a simple application. I've analyzed the differences between my
real world application and the sample and nothing has stuck out as a clue or
cause. The only thing I can do at this point is explain what my application
is doing as best as I can and include the stack trace.

I would also like to invite anyone that is confident they can identify this
problem via a webex and phone session to contact me. I'd love to pay
someone for an hour of time (or more) to take a look and help me find this
bug.

OK, so I will now try to explain the situation.

**I'm using the Composite Application Block framework for this application.

1. User makes shipping label request by clicking a button on the View (MVP)
2. The Presenter requests an Image from a singleton service method (this
method receives base64 encoded image data and constructs an Image instance
and returns)
3. The singleton service method does some post-processing operations on the
image (removing borders, etc)
4. The presenter then calls a print method on another Singleton object which
prints the image.


Here is the stacktrace:
System.InvalidOperationException: Object is currently in use elsewhere.
at System.Drawing.Image.get_RawFormat()
at System.Drawing.Graphics.IgnoreMetafileErrors(Image image, Int32&
errorStatus)
at System.Drawing.Graphics.DrawImage(Image image, Int32 x, Int32 y, Int32
width, Int32 height)
at PMD.Services.PrintingService.document_PrintPage(Object sender,
PrintPageEventArgs e) in C:\PrintingService.cs:line 48
at System.Drawing.Printing.PrintDocument.OnPrintPage(PrintPageEventArgs
e)
at System.Drawing.Printing.PrintDocument._OnPrintPage(PrintPageEventArgs
e)
at System.Drawing.Printing.PrintController.PrintLoop(PrintDocument
document)
at System.Drawing.Printing.PrintController.Print(PrintDocument document)
at System.Drawing.Printing.PrintDocument.Print()
at PMD.Services.PrintingService.Print(Image image, String documentName,
String printerName) in C:\PrintingService.cs:line 39
at PMD.ProcessReturnShipmentViewPresenter.Finished() in
C:\ProcessReturnShipmentViewPresenter.cs:line 111

My drawing code is all wrapped in using blocks like so:
private Image PostProcessLabelImage(Image image)
{
// Creating a new copy to try and work around the
// object already in use bug
Image newCopy = new Bitmap(image.Width, image.Height);

// TODO: move this out to the constructor
Rectangle croppedRec = new Rectangle(2, 2, newCopy.Width-4,
newCopy.Height-4);

using (Graphics g = Graphics.FromImage(newCopy))
{
// There is a black border that we want to remove. Paint the
// image to the new DC minus the 2 pixel border
g.DrawImage(image, croppedRec, croppedRec, GraphicsUnit.Pixel);

// Cover up the endicia logo - BS that they even do that,
// should be OUR logo if anything!
g.FillRectangle(Brushes.White, image.Width - 65, 90,
image.Width - 55, 270);
}

return newCopy;
}

Again, guys, I know this bugs you when someone doesn't post a complete
sample. I really have tried to come up with one but haven't been able to.
If you are interested in the gotomeeting approach please contact me ( sklett
[at] pmd direct com ) I can fire up the debugger and step through the code.

-Steve
 
V

Vista Succubus Hunter

stevek said:
"Object is currently in use elsewhere" - what object? From the stacktrace
in my exception it looks like it's definitly the Image instance but I'm not
*positive*.

Everything in .NET is an object, even variables like string, int, double
etc, etc are objects.
 
S

sklett

Morten Wennevik said:
Hi Steve,

According to this article this error may be caused by a DC object not
properly released, so the DC object is used elsewhere, or not properly
released.

http://msmvps.com/blogs/peterritchi...is-currently-in-use-elsewhere-quot-error.aspx

I don't see a direct use of DC objects in your code, but the Graphics
object
is basically a wrapper around the DC and the stacktrace indicate the
Graphics
object. Maybe you get this error if you try to create two different
Graphics
objects from the same Image before you release either one.

Hi Morten,

Thank you for the reply and the link.

I'm wondering if it's possible that the Graphics object that is created in
my PrintDocument is not being disposed in time and that is the issue. It's
just a guess really and from what I understand it doesn't seem likely but I
thought I'd run it by you anyway.
Here is the code that I'm talking about. As you can see there is a
PrintDocument that is created each time the Print method is called. The bug
is difficult to reproduce so before I spend hours trying to make the problem
happen (it also seems to be affected by the system load) I thought I would
submit the theory to see if it's even possible.


<code>
public void Print(Image image, string documentName, string printerName)
{
Console.WriteLine(
"Print(Image image, string documentName, string printerName)
executed on thread {0}",
System.Threading.Thread.CurrentThread.ManagedThreadId);

_image = image;

PrintDocument document = new PrintDocument();
document.OriginAtMargins = true;
document.PrinterSettings.PrinterName = printerName;
document.DefaultPageSettings.PaperSize = new PaperSize("4x6ShipLbl",
400, 600);
document.DocumentName = documentName;
document.DefaultPageSettings.Margins.Bottom =
document.DefaultPageSettings.Margins.Left =
document.DefaultPageSettings.Margins.Top =
document.DefaultPageSettings.Margins.Right = 5;

document.PrintPage += new PrintPageEventHandler(document_PrintPage);
document.Print();
}

void document_PrintPage(object sender, PrintPageEventArgs e)
{
Console.WriteLine(
"document_PrintPage(object sender, PrintPageEventArgs e) executed on
thread {0}",
System.Threading.Thread.CurrentThread.ManagedThreadId);

e.Graphics.DrawImage(_image,
0,
0,
e.PageBounds.Width - _numPixelsShrinkBy,
e.PageBounds.Height - _numPixelsShrinkBy);

e.HasMorePages = false;
}
</code>

I will probably still experiment with this and post back any results that
are interesting.

Thanks again,
Steve
 
S

sklett

sklett said:
I'm wondering if it's possible that the Graphics object that is created in
my PrintDocument is not being disposed in time and that is the issue.
It's just a guess really and from what I understand it doesn't seem likely
but I thought I'd run it by you anyway.
Here is the code that I'm talking about. As you can see there is a
PrintDocument that is created each time the Print method is called. The
bug is difficult to reproduce so before I spend hours trying to make the
problem happen (it also seems to be affected by the system load) I thought
I would submit the theory to see if it's even possible.

I tried disposing of the PrintDocument after each print and that didn't fix
the problem.

<code>
public void Print(Image image, string documentName, string printerName)
{
_image = image;

using (PrintDocument document = new PrintDocument())
{
document.OriginAtMargins = true;
document.PrinterSettings.PrinterName = printerName;
document.DefaultPageSettings.PaperSize =
new PaperSize("4x6ShipLbl", 400, 600);
document.DocumentName = documentName;
document.DefaultPageSettings.Margins.Bottom =
document.DefaultPageSettings.Margins.Left =
document.DefaultPageSettings.Margins.Top =
document.DefaultPageSettings.Margins.Right = 5;

document.PrintPage += new PrintPageEventHandler(
document_PrintPage);

document.Print();
}
}
</code>
 
S

sklett

Ah! I found it!!!

I'm sure that many of you will NOT be surprised to learn that I was indeed
working with the Image in a separate thread. ;0)
It was a part of the system that I just completely forgot about but sure
enough, it's handed an instance of the Image to work with and that is what's
causign the trouble.

Man it feels good when you finally solve a bug that has been taking days and
days of your time!

-Steve
 

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