Results 1 to 8 of 8

Thread: [2.0] Threading issue...

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Sep 2005
    Posts
    1,547

    [2.0] Threading issue...

    How do you properly do threads? Everytime I try it gives me disposing errors no matter what I tried.

    I tried forcing stopping all the threads before the form closing.

    I tried using a background worker.

    I tried checking if it is disposed.

    I still get these errors.

    (one of them)
    "DragDrop registration did not succeed."
    StatusLabel.Text = num.ToString();
    (It is a menustrip label so there is no .Invoke())

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: [2.0] Threading issue...

    There's no way for us to answer a question like:
    How do you properly do threads?
    That's just too general. You need to tell us:

    1. Exactly what you're trying to achieve.
    2. Exactly how you're trying to achieve it.
    3. Exactly what happens.

    Also, it's not necessary to call Invoke on the object you're accessing. All Invoke does is marshal a method call to a specific thread. Any control that is owned by that thread can do it. If you're using a ToolStripLabel then it will be on a ToolStrip, which is a control. The form itself is a control too.

  3. #3

    Thread Starter
    Frenzied Member
    Join Date
    Sep 2005
    Posts
    1,547

    Re: [2.0] Threading issue...

    CSHARP Code:
    1. void private void DotWorker_Working(object sender, DoWorkEventArgs e)
    2. {
    3.     //In here a class is used, and an event is registered
    4. }
    5. void EventCallback(string info)
    6. {
    7.     if (this.Disposing || this.IsDisposed || StatusLabel.IsDisposed)
    8.         return;
    9.     StatusLabel.Text = info;
    10. }
    11. void Run()
    12. {
    13.     DotWorker.RunWorkerAsync();
    14. }

    The problem is that it gives an exception when the form closes. Even if I force the worker to abort. (The error is in the event callback)

    The only way I have gotten around is

    CSHARP Code:
    1. private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    2.         {
    3.             if (DotWorker.IsBusy)
    4.             {
    5.                 e.Cancel = true;
    6.                 MessageBox.Show("DotWorker is still running...");
    7.             }
    8.         }

    Although then the user cannot close till finished.

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: [2.0] Threading issue...

    You've omitted the critical code.

    I'm going to guess that you're using += to register an event handler. You need to use -= to deregister the event handler or else it remains registered. If you don't deregister the event handler and the event is raised then the event handler will execute, thus setting the Text property of a disposed object.

  5. #5

    Thread Starter
    Frenzied Member
    Join Date
    Sep 2005
    Posts
    1,547

    Re: [2.0] Threading issue...

    Quote Originally Posted by jmcilhinney
    You've omitted the critical code.

    I'm going to guess that you're using += to register an event handler. You need to use -= to deregister the event handler or else it remains registered. If you don't deregister the event handler and the event is raised then the event handler will execute, thus setting the Text property of a disposed object.
    hm, but the class that registers the event is inside the worker method.

    CSHARP Code:
    1. private void DotWorker_Working(object sender, DoWorkEventArgs e)
    2.         {
    3.             Dot dot = new Dot();
    4.             dot.Decrypted += new Dot.DecryptedD(EventCallback);
    5.             //Loop here using dot.
    6.         }

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: [2.0] Threading issue...

    Quote Originally Posted by high6
    hm, but the class that registers the event is inside the worker method.
    That's not true at all. Look at the language you use and think about what the actual reality is. The "class" is not inside the worker method. The variable that refers to the instance of the class, i.e. the object, is declared in the DoWork event handler. That means that you can only access that variable within that method. Objects don't exist in any one thread though. You can access the same object anywhere you have a reference to it. You could have a reference to that same object at the class level, which would allow you to remove an event handler from it anywhere. In fact, if you had such a member variable then you wouldn't need the local variable at all.

    Another point to note is that attaching event handlers in code and then not detaching them is a good way to create memory leaks. In your code you are registering a method in the current object as an event handler. That creates a managed reference to the current object. Objects do not become eligible for garbage collection as long as there exists a managed reference to them, so your current object can never be cleaned up by the garbage collector as long as that event handler is registered.

  7. #7

    Thread Starter
    Frenzied Member
    Join Date
    Sep 2005
    Posts
    1,547

    Re: [2.0] Threading issue...

    Should I add a dispose method to the class that removes all events?

    Also is it possible to leave it as a local variable or do I have to use a member variable?

  8. #8
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: [2.0] Threading issue...

    Generally the maker should be the breaker. Where you create something is where you should destroy it. If you add the event handler in the form you should remove it in the form.

    If you only need to access an object within a single method then you only need a local variable. If you need to access the object in more than one place then obviously that's not enough. If you can pass the object from method to method directly then a member variable isn't required, otherwise it is. This is always the case, not just here.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width