By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
461,981 Members | 561 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 461,981 IT Pros & Developers. It's quick & easy.

"Object in use" error when multiple objects hear event

tlhintoq
Expert 2.5K+
P: 3,525
I'm pretty sure this is language independent and is going to be the same whether it's VC or C# - but my project is C# WIndows Forms just in case.

Does anyone have a good handle on the sequence of events when an event is raised and multiple classes are all subscribed to the event?
  • Does each class get a copy of the argument?
  • Does each class get a pointer/address/ref to the one and only argument?
  • Do all the classes get the argument at once, or is passed in subscriber sequence as it falls out of scope?
  • Can the classes each work independently (own thread) with the argument object, or does one have to complete and release the object so it can be passed to the next class in the order they subscribed.?

I have spent hours trying to find the official answer and either Microsoft won't cop to it, or I can't think of the right search terms.

Here's my situation:
I want to pass an arguments object that has a Bitmap, a string and couple other values each time a given event is raised.
Several other classes are subscribed to that event.
So one should process it and save it, one should email it, one should display it and so on. Every class works fine when it is the only class subscribed, but as more classes subscribe to the event the more often I get an "object in use" error randomly.

The kicker is that each class as soon as it gets the Event with argument, makes a low level clone of the argument and works with the clone. So I just can't figure out how each class with its own clone of the arguments can still be affected by another class with its own clone.

Maybe I'm not making a true clone?
Expand|Select|Wrap|Line Numbers
  1.     public class StepArgs : EventArgs, ICloneable
  2.     {
  3.         private string message = string.Empty;
  4.         private List<string> idlist = new List<string>();
  5.         private Image photo = MyCoolProgram.Properties.Resources.TronBit;//Just a placeholder really
  6.         private string filepath = string.Empty;
  7.  
  8.  
  9.         public string Message
  10.         {
  11.             get { return message; }
  12.             set { message = value; }
  13.         }
  14.         public List<string> IDlist = new List<string>();
  15.         public Image Photo
  16.         {
  17.             get { return photo; }
  18.             set { photo = value; }
  19.         }
  20.  
  21.         public string FilePath
  22.         {
  23.             get { return filepath; }
  24.             set { filepath = value; }
  25.         }
  26.  
  27.  
  28.         public override string ToString()
  29.         {
  30.             return "StepArgs";
  31.         }
  32.         public StepArgs()
  33.         {
  34.             IDlist.Add(string.Empty);
  35.             //IDlist.Clear();
  36.             Message = string.Empty;
  37.             FilePath = string.Empty;
  38.             Photo = ThrillCapture.Properties.Resources.Bit;
  39.         }
  40.  
  41.         #region ICloneable Members
  42.  
  43.         public object Clone()
  44.         {
  45.             return (object)this.MemberwiseClone();
  46.         }
  47.  
  48.         #endregion
  49.     }
  50.  
So I'm asking if anyone can straighten me out on my conceptual understanding of the sequence of what happens to the arguments of event, when subscribed to by multiple classes.
Mar 28 '09 #1
Share this Question
Share on Google+
1 Reply

tlhintoq
Expert 2.5K+
P: 3,525
So guess what ... I found the object in use, and it wasn't my object or argument.
It was the ImageCodecInfo from the System.Drawing.Imaging namespace - as part of the SaveJPG method.

It would appear that when you get this info you are tied to it until the variable that uses it goes out of scope. So if you have another class that also wants to know the codec info... Well, tough luck Charlie.

Expand|Select|Wrap|Line Numbers
  1.                 ImageCodecInfo jpegCodec = getEncoderInfo("image/jpeg");
  2.  
  3.                 EncoderParameters encoderParams = new EncoderParameters(1);
  4.                 encoderParams.Param[0] = qualityParam;
Notice that when you make the first ImageCodecInfo object (line 1) that you aren't doing it with 'new' specifier. One would assume that you are getting some sort of structure back that is a COPY of the codec's information. But I think I have just proven to myself that what you really get back in a handle to the codec information and no other class can establish a new handle until this one is closed (line 3)

I guess System.Drawing is full of this stuff. Its like that thing were if you make an image from path, you are linked to the path unless you copy it into a new image and dump the link one. Thanks M$.

Trial, lots of error, and following step by step with the debugger. Damn I wish I would follow my own advice more often!
Mar 29 '09 #2

Post your reply

Sign in to post your reply or Sign up for a free account.