crossthreading issue

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
 
G

Guest

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
 
S

Stoitcho Goutsev \(100\)

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.
 
W

Willy Denoyette [MVP]

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.
 
A

Andrew Bullock

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
 

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