473,490 Members | 2,458 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Access to object being locked - exception: The object is currently in use elsewhere.

Hi all, I have just finished debugging a windows application and have
solved the problem - however, I want to be sure that I understand the
problem before I move on. Before I detail the problem, this problem
requires some understanding of threading concepts.

Basically, the class contained both a PictureBox object as well as a
corresponding Image object (they both had a copy of the same picture).
The following was used to access the the Image object (I believe the
setter below will result in them both getting a copy of the same image
- but they won't both be pointing at the same image):
[CategoryAttribute("Appearance")]
[DescriptionAttribute("Image1")]
[DefaultValueAttribute(null)]
public Image Image1
{
get { return _image1; }
set
{
_image1 = value;
pictureBox1.Image = value;
}
}

_image1 is an object of type Image and pictureBox1 is an object of type
PictureBox.

Now as you have probably deduced, there is no obviously good reason to
have both an Image object contained in this class, since the two are
always in sync. Now, no problems emerged from this until we made this
application multi-threaded.

Once we made it multi-threaded I got the following error:
The object is currently in use elsewhere.
at System.Drawing.Image.get_Width()
at CustomPictureBox.ScaleImages(Single scaleFactor, Boolean
arrangeHorizontally) in c:\test\custompicturebox.cs:line 433
at CustomPictureBox.OnResize(Object sender, EventArgs e) in
c:\test\autopicturebox.cs:line 282

By simply removing the redundant Image object from the class and of
course any use of that member variable the problem went away.

Now in an attempt to get the most from the experience I have attempted
to make a small application to reproduce the problem to show other
people why this happens - but I can't get a small application to
reproduce the problem even though I understand the essence of the
problem.

I would be happy to send this small program to others to see if that
can "fix it" so that it will break in the above manner. But
essentially I'm just looking a bare bones windows application that
loads a picture, uses multi-threading and then results in a race
condition because of code similar to the above.

Thanks,
Novice

Nov 17 '05 #1
4 5006
Sorry, I meant to say that they _are_ pointing at the same Image object
- this is why there is a race condition. They do not have a copy of
the same image.

Nov 17 '05 #2
What exactly are you trying to do when the exception gets thrown? That
code would help tremendously.

The one thing that I can definitely tell you is that if you are going to
perform any operations on the PictureBox (and it seems you are doing
something, either directly or indirectly from the text of the exception),
then you should do it in the UI thread. Windows controls need to have calls
to them (for the most part) made on the thread they were created on. If you
don't, then you get unexplained results.

If you are doing this, then you might want to reconsider the
multithreaded approach, or make your methods on this class thread safe.

I would post the example that you tried to draw up as well.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

<6t**@qlink.queensu.ca> wrote in message
news:11*********************@g43g2000cwa.googlegro ups.com...
Hi all, I have just finished debugging a windows application and have
solved the problem - however, I want to be sure that I understand the
problem before I move on. Before I detail the problem, this problem
requires some understanding of threading concepts.

Basically, the class contained both a PictureBox object as well as a
corresponding Image object (they both had a copy of the same picture).
The following was used to access the the Image object (I believe the
setter below will result in them both getting a copy of the same image
- but they won't both be pointing at the same image):
[CategoryAttribute("Appearance")]
[DescriptionAttribute("Image1")]
[DefaultValueAttribute(null)]
public Image Image1
{
get { return _image1; }
set
{
_image1 = value;
pictureBox1.Image = value;
}
}

_image1 is an object of type Image and pictureBox1 is an object of type
PictureBox.

Now as you have probably deduced, there is no obviously good reason to
have both an Image object contained in this class, since the two are
always in sync. Now, no problems emerged from this until we made this
application multi-threaded.

Once we made it multi-threaded I got the following error:
The object is currently in use elsewhere.
at System.Drawing.Image.get_Width()
at CustomPictureBox.ScaleImages(Single scaleFactor, Boolean
arrangeHorizontally) in c:\test\custompicturebox.cs:line 433
at CustomPictureBox.OnResize(Object sender, EventArgs e) in
c:\test\autopicturebox.cs:line 282

By simply removing the redundant Image object from the class and of
course any use of that member variable the problem went away.

Now in an attempt to get the most from the experience I have attempted
to make a small application to reproduce the problem to show other
people why this happens - but I can't get a small application to
reproduce the problem even though I understand the essence of the
problem.

I would be happy to send this small program to others to see if that
can "fix it" so that it will break in the above manner. But
essentially I'm just looking a bare bones windows application that
loads a picture, uses multi-threading and then results in a race
condition because of code similar to the above.

Thanks,
Novice

Nov 17 '05 #3
Yeah, I wanted to post the code, but I figured it would be too much to
digest in one post. Here is what I have tried - you will of course
have to change the file (test.bmp) that is getting loaded or create a
file of that name in your working directory (usually the directory your
binary gets compiled into). This application works - I would like to
tweak it so that I get the aforementioned exception when I hit the
button - I tried doing all sorts of processing in Foo before I call
Foo2, but that didn't seem to help:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

using System.Threading;
using System.IO;

using System.Drawing.Imaging;

namespace ThreadTest
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button button1;

//private Another another;
private System.Windows.Forms.PictureBox pictureBox1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.textBox1.Location = new System.Drawing.Point(0, 390);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.textBox1.Size = new System.Drawing.Size(576, 192);
this.textBox1.TabIndex = 3;
this.textBox1.Text = "";
//
// button1
//
this.button1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.button1.Location = new System.Drawing.Point(0, 367);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(576, 23);
this.button1.TabIndex = 1;
this.button1.Text = "Start";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// pictureBox1
//
this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.pictureBox1.Location = new System.Drawing.Point(0, 0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(576, 367);
this.pictureBox1.TabIndex = 2;
this.pictureBox1.TabStop = false;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(576, 582);
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.button1);
this.Controls.Add(this.textBox1);
this.Name = "Form1";
this.Text = "Thread Test";
this.ResumeLayout(false);

}
#endregion

Image _image1;

[CategoryAttribute("Appearance")]
[DescriptionAttribute("Image1")]
[DefaultValueAttribute(null)]
public Image Image1
{
get { return _image1; }
set
{
_image1 = value; pictureBox1.Image = value;
}
}

private void LoadImage (){
String image_filename = "test.bmp";
if(File.Exists(image_filename))
{
try
{
Image1 = Image.FromFile( image_filename );
}
catch
{
Image1 = null;
}
}
}

private void Foo ()
{
try
{
int imageWidth = (Image1 != null) ? Image1.Width : 0;
pictureBox1.Width = imageWidth + 100;
int imageHeight = Image1.Height;
double widthAsDouble = imageWidth;
double testing = 0f;
for (int i = 0;i < 20; i++){
testing += Image1.Width * Math.Max(Math.PI, widthAsDouble);
}

Foo2();
}
catch (Exception exception)
{
String exceptionStr = "exception:
"+exception.Message+System.Environment.NewLine + exception.StackTrace +
System.Environment.NewLine + System.Environment.NewLine;
textBox1.AppendText(exceptionStr);
}
}

private void Foo2 ()
{
try
{
int imageWidth = (Image1 != null) ? Image1.Width : 0;
pictureBox1.Width = imageWidth + 100;
}
catch (Exception exception)
{
String exceptionStr = "exception:
"+exception.Message+System.Environment.NewLine + exception.StackTrace +
System.Environment.NewLine + System.Environment.NewLine;
textBox1.AppendText(exceptionStr);
}
}

private void ThreadedMethod(object JustTesting)
{
LoadImage();
Foo();
}

private void button1_Click(object sender, System.EventArgs e)
{
try
{
Toub.Threading.ManagedThreadPool.QueueUserWorkItem ( new
WaitCallback(ThreadedMethod), null );
}
catch (Exception exception)
{
String exceptionStr = "exception:
"+exception.Message+System.Environment.NewLine + exception.StackTrace +
System.Environment.NewLine + System.Environment.NewLine;
textBox1.AppendText(exceptionStr);
}
}

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

}
}

Nov 17 '05 #4
I got it to happen... but I created a separate UserControl, threw the
Foo and Foo2 methods in there and bingo... not really happy with that,
because in the application it was like 90% reproducible... in this test
application it only happens 5 or 10% of the time. I realize I could
just create a tight loop and generate a bunch of threads and have them
access it - but I want it to occur without having multiple threads in
the Foo call stack - I want this error to occur because of these extra
references to the Image object.

Anyway, I'm guessing this is the end of this thread...

Novice

Nov 17 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
3620
by: Kenneth Courville | last post by:
Hello, I'm looking for assistance with the Access object model. I know this is VB, but I'm building an Office Add-using C# directed at Access 2002. I'm literate in VB, so you can reply in VB... I...
29
15472
by: Patrick | last post by:
I have the following code, which regardless which works fine and logs to the EventViewer regardless of whether <processModel/> section of machine.config is set to username="SYSTEM" or "machine" ...
8
3540
by: Sharon | last post by:
I have a DataGrid control on a Form. The data of the control is added by another application by Remoting. It means that a worker thread is invoking a UI thread. Therefore I used a delegate in the...
9
3813
by: Wayne Smith | last post by:
I've come up against a major headache that I can't seem to find a solution for but I'm sure there must be a workaround and I would really be grateful of any help. I'm currently building a web...
1
2122
by: chad | last post by:
system.InvalidOperationException: the object is currently in use elsewhere... has anyone experienced this error before? I am occasionally getting this error. I can't figure out what could...
3
2194
by: boeledi | last post by:
Dear All, (First of all this is not a c# piece of code but it does not really matter). I would really appreciate if someone could help me. I am developing an ASP.NET web site and I have to...
11
8386
bhcob1
by: bhcob1 | last post by:
Hi, Whenever I delete a record my command button, the record deletes, a list displaying all records is updated and then a message box appears: Microsoft Access can't find the field 'I' referred to...
4
2262
by: =?Utf-8?B?Qm9uaQ==?= | last post by:
Hi, I got this problem. I'm implementing a pluggable winform program. My plugins are usercontrol and I load them in my program through a interface. Now if I close my application an error occurs:...
0
2310
by: para15000 | last post by:
Hello I have a C# desktop application in which one thread that I create continously gets an image from a source(it's a digital camera actually) and puts it on a panel(panel.Image = img) in the...
0
7108
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
6967
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7142
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
6847
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7352
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
4875
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3071
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1383
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
272
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.