Thread problem with control delegate

J

jecheney

Hi,
From the code below, I have this method/delegate which is called from
another thread, Debug_Console is a listbox control on my main form, i
created the delegate to avoid the cross threading error. Now the
strange thing is, when i call the method from my other thread, the
entry string is added to the listbox, but it also throws an exception
after the string is added. I cant work out why.

The exception is:
=========================
System.InvalidOperationException: Cross-thread operation not valid:
Control 'DebugConsole' accessed from a thread other than the thread it
was created on.
at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.Control.SendMessage(Int32 msg, Int32
wparam, String lparam)
at System.Windows.Forms.ListBox.NativeAdd(Object item)
at System.Windows.Forms.ListBox.ObjectCollection.AddInternal(Object
item)
at System.Windows.Forms.ListBox.ObjectCollection.Add(Object item)
at UsenetProject.MainForm.Debug_Console_Add_Item(String entry) in C:
\Users\Jack\Documents\Misc Stuff\My Programs\UsenetProject
\UsenetProject\UsenetProject\Form1.cs:line 46
=========================

I thought the whole point of invoking the new delgate is to avoid the
cross threading problem, what am i doing wrong?

My code:
public delegate void UpdateDebugConsoleDelegate(string entry);

public void Debug_Console_Add_Item(string entry)
{
if (this.DebugConsole.InvokeRequired)
{
UpdateDebugConsoleDelegate theDelegate = new
UpdateDebugConsoleDelegate(this.Debug_Console_Add_Item);
this.Invoke(theDelegate, new object[] { entry });
}

try
{
DebugConsole.Items.Add(entry);
}
catch(Exception e)
{
MessageBox.Show(e.ToString());
}
}


Thanks very much for any help,
Jack
 
P

Peter Duniho

[...]
I thought the whole point of invoking the new delgate is to avoid the
cross threading problem, what am i doing wrong?

Looks to me like you left out an "else". :)

Your method should only do the real work in the
!this.DebugConsole.InvokeRequired case. Put the whole try/catch block
where you do the real work in the else clause of your if statement and
everything should be fine.

Pete
 
J

jecheney

Hi,
From the code below, I have this method/delegate which is called from

another thread, Debug_Console is a listbox control on my main form, i
created the delegate to avoid the cross threading error. Now the
strange thing is, when i call the method from my other thread, the
entry string is added to the listbox, but it also throws an exception
after the string is added. I cant work out why.

The exception is:
=========================
System.InvalidOperationException: Cross-thread operation not valid:
Control 'DebugConsole' accessed from a thread other than the thread it
was created on.
at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.Control.SendMessage(Int32 msg, Int32
wparam, String lparam)
at System.Windows.Forms.ListBox.NativeAdd(Object item)
at System.Windows.Forms.ListBox.ObjectCollection.AddInternal(Object
item)
at System.Windows.Forms.ListBox.ObjectCollection.Add(Object item)
at UsenetProject.MainForm.Debug_Console_Add_Item(String entry) in C:
\Users\Jack\Documents\Misc Stuff\My Programs\UsenetProject
\UsenetProject\UsenetProject\Form1.cs:line 46
=========================

I thought the whole point of invoking the new delgate is to avoid the
cross threading problem, what am i doing wrong?

My code:
public delegate void UpdateDebugConsoleDelegate(string entry);

public void Debug_Console_Add_Item(string entry)
{
if (this.DebugConsole.InvokeRequired)
{
UpdateDebugConsoleDelegate theDelegate = new
UpdateDebugConsoleDelegate(this.Debug_Console_Add_Item);
this.Invoke(theDelegate, new object[] { entry });
}

try
{
DebugConsole.Items.Add(entry);
}
catch(Exception e)
{
MessageBox.Show(e.ToString());
}
}

Thanks very much for any help,
Jack

Brilliant thanks very much, that fixed it.
 
J

jecheney

Given the above (working) code, i now have the problem that if i close
the main form/program while the new thread is working, I get an
exception that it cannot access a disposed object.

what's the best way to avoid this problem? i.e stopping the thread
before the main form object is disposed.
 
P

Peter Duniho

Given the above (working) code, i now have the problem that if i close
the main form/program while the new thread is working, I get an
exception that it cannot access a disposed object.

what's the best way to avoid this problem? i.e stopping the thread
before the main form object is disposed.

Hard to say for sure. It depends on what exactly your form and your
thread do and are doing when the form is closed. However, the two usual
approaches would be to either alert the thread to stop processing and exit
before you close the form, or to have the thread check to see if the form
is still around before trying to use it (in the invoking method, for
example).

Pete
 

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