Re: [2.0] Threading issue...
There's no way for us to answer a question like:
Quote:
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.
Re: [2.0] Threading issue...
CSHARP Code:
void private void DotWorker_Working(object sender, DoWorkEventArgs e)
{
//In here a class is used, and an event is registered
}
void EventCallback(string info)
{
if (this.Disposing || this.IsDisposed || StatusLabel.IsDisposed)
return;
StatusLabel.Text = info;
}
void Run()
{
DotWorker.RunWorkerAsync();
}
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:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (DotWorker.IsBusy)
{
e.Cancel = true;
MessageBox.Show("DotWorker is still running...");
}
}
Although then the user cannot close till finished.
Re: [2.0] Threading issue...
You've omitted the critical code. :rolleyes:
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.
Re: [2.0] Threading issue...
Quote:
Originally Posted by jmcilhinney
You've omitted the critical code. :rolleyes:
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:
private void DotWorker_Working(object sender, DoWorkEventArgs e)
{
Dot dot = new Dot();
dot.Decrypted += new Dot.DecryptedD(EventCallback);
//Loop here using dot.
}
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.
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?
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.