473,226 Members | 1,417 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,226 software developers and data experts.

Cross Thread Communications

Hi everyone,

I have a Socket derived class that parses the received data into a message,
populates a object with that information and then tries to send an event to
inform the owner of the socket that there is message to be processed. But
this is not working as the socket receiver method seems to be in a different
thread then the form that owns the socket.

The receive callback gets the data from the socket and process the
information, once it constructs a full message from it then it calls a
delegate if the delegate is set.

The method that handles this event needs to change some controls on the form
and when I do that I get the exception:
Cross-thread operation not valid: Control 'syncButton' accessed from a
thread other than the thread it was created on.

I would appreciate any suggestions on solving this.

class LSSocket : Socket
{
public event ProcessMessageHandler ProcessMessageEvent;

public void OnReceiveData(IAsyncResult)
{
....
if (ProcessMessageEvent != null)
{
ProcessMessageEvent(this, new ProcessMessageArgs(Msg));
}
}
}

class ProcessMessageArgs : System.EventArgs
{
public ProcessMessageArgs(LSMessage msg)
{
this.msg = msg;
}
public LSMessage msg;
}
delegate void ProcessMessageHandler(object sender, ProcessMessageArgs
e);

I would have had to use PostThreadMessage in native windows development, but
I can't figure out what I need to use in this situation.

AliR.
Aug 5 '08 #1
6 2356
On Aug 5, 12:48 pm, "AliR \(VC++ MVP\)" <A...@online.nospamwrote:
Hi everyone,

I have a Socket derived class that parses the received data into a message,
populates a object with that information and then tries to send an event to
inform the owner of the socket that there is message to be processed. But
this is not working as the socket receiver method seems to be in a different
thread then the form that owns the socket.

The receive callback gets the data from the socket and process the
information, once it constructs a full message from it then it calls a
delegate if the delegate is set.

The method that handles this event needs to change some controls on the form
and when I do that I get the exception:
Cross-thread operation not valid: Control 'syncButton' accessed from a
thread other than the thread it was created on.

I would appreciate any suggestions on solving this.

class LSSocket : Socket
{
public event ProcessMessageHandler ProcessMessageEvent;

public void OnReceiveData(IAsyncResult)
{
....
if (ProcessMessageEvent != null)
{
ProcessMessageEvent(this, new ProcessMessageArgs(Msg));
}
}
}

class ProcessMessageArgs : System.EventArgs
{
public ProcessMessageArgs(LSMessage msg)
{
this.msg = msg;
}
public LSMessage msg;
}
delegate void ProcessMessageHandler(object sender, ProcessMessageArgs
e);

I would have had to use PostThreadMessage in native windows development, but
I can't figure out what I need to use in this situation.

AliR.
Use Control.Invoke to execute the event in the UI thread.
Aug 5 '08 #2
"Ignacio Machin ( .NET/ C# MVP )" <ig************@gmail.comwrote in
message
news:1f**********************************@m44g2000 hsc.googlegroups.com...
On Aug 5, 12:48 pm, "AliR \(VC++ MVP\)" <A...@online.nospamwrote:
>Hi everyone,

I have a Socket derived class that parses the received data into a
message,
populates a object with that information and then tries to send an event
to
inform the owner of the socket that there is message to be processed.
But
this is not working as the socket receiver method seems to be in a
different
thread then the form that owns the socket.

The receive callback gets the data from the socket and process the
information, once it constructs a full message from it then it calls a
delegate if the delegate is set.

The method that handles this event needs to change some controls on the
form
and when I do that I get the exception:
Cross-thread operation not valid: Control 'syncButton' accessed from a
thread other than the thread it was created on.

I would appreciate any suggestions on solving this.

class LSSocket : Socket
{
public event ProcessMessageHandler ProcessMessageEvent;

public void OnReceiveData(IAsyncResult)
{
....
if (ProcessMessageEvent != null)
{
ProcessMessageEvent(this, new
ProcessMessageArgs(Msg));
}
}
}

class ProcessMessageArgs : System.EventArgs
{
public ProcessMessageArgs(LSMessage msg)
{
this.msg = msg;
}
public LSMessage msg;
}
delegate void ProcessMessageHandler(object sender, ProcessMessageArgs
e);

I would have had to use PostThreadMessage in native windows development,
but
I can't figure out what I need to use in this situation.

AliR.

Use Control.Invoke to execute the event in the UI thread.
I looked at Control.Invoke, but wasn't really sure where it would apply. A
little more explanation would be great.

Are you saying that I have to use that in event hander method in my form
class to do the UI manipulation? Or am I supposed to use it in place of the
event hander call? Or am I supposed to call the event handler delegate
using the Invoke method?

Here is the event handler method:
public void ProcessMessage(object sender, ProcessMessageArgs e)
{
switch (e.msg.m_Command)
{
case MSG_SERVERIP: ServerIP = e.msg.m_Address;
ServerPort = 29308;
syncButton.Enabled = true;
break;
default: Debug.Print("Oh Oh");
break;
}
}

AliR
Aug 5 '08 #3
"AliR (VC++ MVP)" <Al**@online.nospamwrote in message
news:QW*******************@nlpi061.nbdc.sbc.com...
"Ignacio Machin ( .NET/ C# MVP )" <ig************@gmail.comwrote in
message
news:1f**********************************@m44g2000 hsc.googlegroups.com...
>On Aug 5, 12:48 pm, "AliR \(VC++ MVP\)" <A...@online.nospamwrote:
>>Hi everyone,

I have a Socket derived class that parses the received data into a
message,
populates a object with that information and then tries to send an event
to
inform the owner of the socket that there is message to be processed.
But
this is not working as the socket receiver method seems to be in a
different
thread then the form that owns the socket.

The receive callback gets the data from the socket and process the
information, once it constructs a full message from it then it calls a
delegate if the delegate is set.

The method that handles this event needs to change some controls on the
form
and when I do that I get the exception:
Cross-thread operation not valid: Control 'syncButton' accessed from a
thread other than the thread it was created on.

I would appreciate any suggestions on solving this.

class LSSocket : Socket
{
public event ProcessMessageHandler ProcessMessageEvent;

public void OnReceiveData(IAsyncResult)
{
....
if (ProcessMessageEvent != null)
{
ProcessMessageEvent(this, new
ProcessMessageArgs(Msg));
}
}
}

class ProcessMessageArgs : System.EventArgs
{
public ProcessMessageArgs(LSMessage msg)
{
this.msg = msg;
}
public LSMessage msg;
}
delegate void ProcessMessageHandler(object sender,
ProcessMessageArgs
e);

I would have had to use PostThreadMessage in native windows development,
but
I can't figure out what I need to use in this situation.

AliR.

Use Control.Invoke to execute the event in the UI thread.

I looked at Control.Invoke, but wasn't really sure where it would apply.
A little more explanation would be great.

Are you saying that I have to use that in event hander method in my form
class to do the UI manipulation? Or am I supposed to use it in place of
the event hander call? Or am I supposed to call the event handler
delegate using the Invoke method?

Here is the event handler method:
public void ProcessMessage(object sender, ProcessMessageArgs e)
{
switch (e.msg.m_Command)
{
case MSG_SERVERIP: ServerIP = e.msg.m_Address;
ServerPort = 29308;
syncButton.Enabled = true;
break;
default: Debug.Print("Oh Oh");
break;
}
}

AliR
I think I got it. (Correctly or not I don't know.)
Beside the event member, I added a parent form object to the class of type
Control.

delegate void ProcessMessageHandler(LSMessage Msg);
class LSSocket : Socket
{
public event ProcessMessageHandler ProcessMessageEvent;
public Form ParentForm = null;

public void OnReceiveData(IAsyncResult)
{
//pares data into a LSMessage class (Msg)
....
if (ProcessMessageEvent != null && ParentForm != null)
{
// ProcessMessageEvent(this, new
ProcessMessageArgs(Msg));
ParentForm.Invoke(ProcessMessageEvent,Msg);
}
}
.....
}

Hopefully this is the right way of doing it.

AliR.
Aug 5 '08 #4
On Tue, 05 Aug 2008 11:25:58 -0700, AliR (VC++ MVP) <Al**@online.nospam>
wrote:
[...]
public void ProcessMessage(object sender, ProcessMessageArgs e)
{
switch (e.msg.m_Command)
{
case MSG_SERVERIP: ServerIP = e.msg.m_Address;
ServerPort = 29308;
syncButton.Enabled = true;
break;
default: Debug.Print("Oh Oh");
break;
}
}
Try:

public void ProcessMessage(object sender, ProcessMessageArgs e)
{
switch (e.msg.m_Command)
{
case MSG_SERVERIP: ServerIP = e.msg.m_Address;
ServerPort = 29308;
syncButton.Invoke((MethodInvoker)delegate {
syncButton.Enabled = true } );
break;
default: Debug.Print("Oh Oh");
break;
}
}

Not only does that avoid having to track a specific parent control in your
event-raising class, IMHO it's better for the GUI-specific stuff to stay
in the GUI-specific class.

Pete
Aug 5 '08 #5

"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Tue, 05 Aug 2008 11:25:58 -0700, AliR (VC++ MVP) <Al**@online.nospam>
wrote:
>[...]
public void ProcessMessage(object sender, ProcessMessageArgs e)
{
switch (e.msg.m_Command)
{
case MSG_SERVERIP: ServerIP = e.msg.m_Address;
ServerPort = 29308;
syncButton.Enabled = true;
break;
default: Debug.Print("Oh Oh");
break;
}
}

Try:

public void ProcessMessage(object sender, ProcessMessageArgs e)
{
switch (e.msg.m_Command)
{
case MSG_SERVERIP: ServerIP = e.msg.m_Address;
ServerPort = 29308;
syncButton.Invoke((MethodInvoker)delegate {
syncButton.Enabled = true } );
break;
default: Debug.Print("Oh Oh");
break;
}
}

Not only does that avoid having to track a specific parent control in your
event-raising class, IMHO it's better for the GUI-specific stuff to stay
in the GUI-specific class.

Pete
Very cool, thank you. I had no idea how to use Invoke! As you can tell
I'm a newbee.

AliR.
Aug 5 '08 #6
On Aug 5, 2:25 pm, "AliR \(VC++ MVP\)" <A...@online.nospamwrote:
"Ignacio Machin ( .NET/ C# MVP )" <ignacio.mac...@gmail.comwrote in
messagenews:1f**********************************@m 44g2000hsc.googlegroups.com...
On Aug 5, 12:48 pm, "AliR \(VC++ MVP\)" <A...@online.nospamwrote:
Hi everyone,
I have a Socket derived class that parses the received data into a
message,
populates a object with that information and then tries to send an event
to
inform the owner of the socket that there is message to be processed.
But
this is not working as the socket receiver method seems to be in a
different
thread then the form that owns the socket.
The receive callback gets the data from the socket and process the
information, once it constructs a full message from it then it calls a
delegate if the delegate is set.
The method that handles this event needs to change some controls on the
form
and when I do that I get the exception:
Cross-thread operation not valid: Control 'syncButton' accessed from a
thread other than the thread it was created on.
I would appreciate any suggestions on solving this.
class LSSocket : Socket
{
public event ProcessMessageHandler ProcessMessageEvent;
public void OnReceiveData(IAsyncResult)
{
....
if (ProcessMessageEvent != null)
{
ProcessMessageEvent(this, new
ProcessMessageArgs(Msg));
}
}
}
class ProcessMessageArgs : System.EventArgs
{
public ProcessMessageArgs(LSMessage msg)
{
this.msg = msg;
}
public LSMessage msg;
}
delegate void ProcessMessageHandler(object sender, ProcessMessageArgs
e);
I would have had to use PostThreadMessage in native windows development,
but
I can't figure out what I need to use in this situation.
AliR.
Use Control.Invoke to execute the event in the UI thread.

I looked at Control.Invoke, but wasn't really sure where it would apply. A
little more explanation would be great.

Are you saying that I have to use that in event hander method in my form
class to do the UI manipulation?
Yes, in windows forms the controls should only be accessed from the
UI thread. You can make an event to be executed in the UI thread (or
more exactly in the control's creation thread, that in the current
implementation is the UI) by using Control.Invoke.

Invoke what does is put a message in the message pump that will be
executed as any other message in a win. app.
Aug 5 '08 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: HairlipDog58 | last post by:
Hello, There are several 'cross-thread operation not valid' exception postings in the MSDN discussion groups, but none address my exact situation. I have authored a .NET component in Visual C#...
3
by: TClancey | last post by:
I'm confused! Probably becuase I know little about threads, and really should. But... I have a serial port control, when it reads data I want to update several things, database fields and...
13
by: LordHog | last post by:
Hello all, I have a little application that needs to poll a device (CAN communications) every 10 to 15 ms otherwise the hardware buffer might overflow when there are message burst on the bus. I...
11
by: Jon Slaughter | last post by:
Is there any way to start a terminated thread without using a pool or creating a new thread object? void counter() { clicks = 0; clock.Start(); while (counterActive) { clicks++;
0
by: veera ravala | last post by:
ServiceNow is a powerful cloud-based platform that offers a wide range of services to help organizations manage their workflows, operations, and IT services more efficiently. At its core, ServiceNow...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.