crossthreading issue

  • Thread starter Thread starter Andrew Bullock
  • Start date Start date
A

Andrew Bullock

Hi, I've got a wierd problem...

Here is my code:

public partial class frmMain : Form
{
private MYClass myClass;

private void btnRun_Click(object sender, EventArgs e)
{
myClass = new MYClass(new CallBack(doStuff));
Thread t1 = new Thread(new ThreadStart(myClass.Run));
t1.Start();
}

private void doStuff()
{
pictureBox1.Image = myClass.getPicture();

}
}

///////////////////////////////////////

public delegate void CallBack();
class MYClass
{
private CallBack CallBackMethod;

public MYClass(CallBack cb)
{
CallBackMethod = cb;
}
public void Run()
{
// do something useful
CallBackMethod();
}
public Bitmap getPicture()
{
// return an img
}
}
///////////////////////////////////////////////////////////////////


in doStuff() i grab data back from myClass like this:

myClass.getData();

and then display it in pictureboxes, listboxes etc in the normal way
(not using invoke - because i thought the point in callbacks was to
avoid invoke). SOMETIMES (ive not worked out when/why) I get a
cross-threading error:

"Cross-thread operation not valid: Control '' accessed from a thread
other than the thread it was created on."

When the debugger takes me to break mode to display the error, if i just
click the run button again, it continues fine :s Sometimes this error
does not occur at all.

Can anyone tell me why, and then what I can do about it?


Thanks
Andrew
 
You shouldn't call doStuff directly if u are not in UI thread. Use *Invoke
for this reason

Detailed explanation is here
http://www.yoda.arachsys.com/csharp/threads/winforms.shtml
Hi, I've got a wierd problem...

Here is my code:

public partial class frmMain : Form
{
private MYClass myClass;

private void btnRun_Click(object sender, EventArgs e)
{
myClass = new MYClass(new CallBack(doStuff));
Thread t1 = new Thread(new ThreadStart(myClass.Run));
t1.Start();
}

private void doStuff()
{
pictureBox1.Image = myClass.getPicture();

}
}

///////////////////////////////////////

public delegate void CallBack();
class MYClass
{
private CallBack CallBackMethod;

public MYClass(CallBack cb)
{
CallBackMethod = cb;
}
public void Run()
{
// do something useful
CallBackMethod();
}
public Bitmap getPicture()
{
// return an img
}
}
///////////////////////////////////////////////////////////////////


in doStuff() i grab data back from myClass like this:

myClass.getData();

and then display it in pictureboxes, listboxes etc in the normal way
(not using invoke - because i thought the point in callbacks was to
avoid invoke). SOMETIMES (ive not worked out when/why) I get a
cross-threading error:

"Cross-thread operation not valid: Control '' accessed from a thread
other than the thread it was created on."

When the debugger takes me to break mode to display the error, if i just
click the run button again, it continues fine :s Sometimes this error
does not occur at all.

Can anyone tell me why, and then what I can do about it?

--
WBR,
Michael Nemtsev :: blog: http://spaces.msn.com/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
 
Andrew,

Callbacks doesn't avoid using Control.Invoke. Calling a callback is the same
as calling a method directly - it executes in the context of the calling
thread. If you use .NET 2.0 and ther BackgroundWorker than its Events
ProgressChanged and RunWorkerComplete are executed in the UI thread so you
don't need to call Control.Invoke from within these event hadnlers.
 
message | Hi, I've got a wierd problem...
|
| Here is my code:
|
| public partial class frmMain : Form
| {
| private MYClass myClass;
|
| private void btnRun_Click(object sender, EventArgs e)
| {
| myClass = new MYClass(new CallBack(doStuff));
| Thread t1 = new Thread(new ThreadStart(myClass.Run));
| t1.Start();
| }
|
| private void doStuff()
| {
| pictureBox1.Image = myClass.getPicture();
|
| }
| }
|
| ///////////////////////////////////////
|
| public delegate void CallBack();
| class MYClass
| {
| private CallBack CallBackMethod;
|
| public MYClass(CallBack cb)
| {
| CallBackMethod = cb;
| }
| public void Run()
| {
| // do something useful
| CallBackMethod();
| }
| public Bitmap getPicture()
| {
| // return an img
| }
| }
| ///////////////////////////////////////////////////////////////////
|
|
| in doStuff() i grab data back from myClass like this:
|
| myClass.getData();
|
| and then display it in pictureboxes, listboxes etc in the normal way
| (not using invoke - because i thought the point in callbacks was to
| avoid invoke). SOMETIMES (ive not worked out when/why) I get a
| cross-threading error:
|
| "Cross-thread operation not valid: Control '' accessed from a thread
| other than the thread it was created on."
|
| When the debugger takes me to break mode to display the error, if i just
| click the run button again, it continues fine :s Sometimes this error
| does not occur at all.
|
| Can anyone tell me why, and then what I can do about it?
|
|
| Thanks
| Andrew
|

Just to add what Michael and Stoitcho said, there is no reason to run this
on a separate thread, the action "getPicture" only takes a few milliseconds
to complete, so you won't freeze the UI thread at all.

Willy.
 
Stoitcho said:
Andrew,

Callbacks doesn't avoid using Control.Invoke. Calling a callback is the same
as calling a method directly - it executes in the context of the calling
thread. If you use .NET 2.0 and ther BackgroundWorker than its Events
ProgressChanged and RunWorkerComplete are executed in the UI thread so you
don't need to call Control.Invoke from within these event hadnlers.


Ace, thanks for that :)

Andrew
 
Back
Top