I'm having a strange problem. I'm using SocketIO4Net Client for my program written in C#. The program communicates with server written in NodeJS & SocketIO. I'm able to send & receive data between my program & server using 'socket.emit()' & 'socket.On()' methods in SocketIO4NET Client. However, when i try to update a textbox in the GUI with the data i received from the server, nothing happens. But, if i use 'MessageBox.Show()' method, i can display the data i received. I'm using the following code for receiving data:
public Form1()
{
InitializeComponent();
socket = new Client("http://127.0.0.1:80/");
socket.On("message", (data) =>
{
String msg = data.Json.Args[0].ToString();
MessageBox.Show(msg,"Received Data");
rxtxtbox.Text = msg;
});
socket.Connect();
}
For sending data:
private void sendbtn_Click(object sender, EventArgs e)
{
String msg = msgtxtbox.Text.ToString();
socket.Emit("private message", msg);
}
The above code works fine. But its not updating the TextBox 'rxtxtbox'. If I move the line "rxtxtbox.Text = msg;" above "MessageBox.Show();", then nothing will happen on receiving the "message" event. I tried setting breakpoints & watching the value of the variable "msg" & its fine. I tried declaring another function just to update the textbox & passing "msg" to it & still getting no results! I think this has something to do with waiting for "message" event? I tried "Application.DoEvents()" and "rxtxtbox.Refresh()" methods & still no luck! I'm new to C#. Please help!
You mention that if you place the MessageBox.Show in front of the rxtxtbox.Text - you see the payload data, but having the rxtxtbox.Text first - nothing at all happens.
The event handers from socketIO4Net definitely run on a background thread, so I'd bet you are throwing an exception updating the UI control - from this non-UI thread. My understanding of MessageBox is that it is not tied to the UI, so it could be called from non-ui threads w/o issue.
Try this in place of your rxtxtbox.Text = msg line:
rxtxtbox.Invoke(new Action(() => rxtxtbox.Text = msg)));
This uses something known as a lambda express to create an anonymous delegate that will be executed on the thread that owns the control (textbox in this case) underlying handle.
You could also place this line right before you update the Text property, and inspect it (if true, you are indeed on a non-ui thread, and have found your problem):
bool state = rxtxtbox.InvokeRequired;
There are various ways to deal with updates to the GUI from non-ui threads. Search multithreading winforms gui C# etc here on SO. Any messages raised from socketio4net will need to be handled appropriately, or you will throw UI thread exceptions.