I'm doing async network in C#.NET with the TcpClient
and TcpListener
classes.
I use WinForms for the GUI.
Whenever I receive data from a remote computer, the operation is done on a different underlying thread.
What I need to do is to update the GUI of my application whenever I receive a network response.
开发者_如何学JAVA// this method is called whenever data is received
// it's async so it runs on a different thread
private void OnRead(IAsyncResult result)
{
// update the GUI here, which runs on the main thread
// (a direct modification of the GUI would throw a cross-thread GUI exception)
}
How can I achieve that?
In Winforms you need to use Control.Invoke Method (Delegate) to make sure that control is updated in the UI thread.
Example:
public static void PerformInvoke(Control ctrl, Action action)
{
if (ctrl.InvokeRequired)
ctrl.Invoke(action);
else
action();
}
Usage:
PerformInvoke(textBox1, () => { textBox1.Text = "test"; });
in GUI write function like this:
public void f() {
MethodInvoker method = () => {
// body your function
};
if ( InvokeRequired ) {
Invoke( method ); // or BeginInvoke(method) if you want to do this asynchrous
} else {
method();
}
}
if you in other thread call this function it will be calling in GUI thread
I added an extension method to the code suggested by Alex. It gets even better!
// Extension method
public static class GuiHelpers
{
public static void PerformInvoke(this Control control, Action action)
{
if (control.InvokeRequired)
control.Invoke(action);
else
action();
}
}
// Example of usage
private void EnableControls()
{
panelMain.PerformInvoke(delegate { panelMain.Enabled = true; });
linkRegister.PerformInvoke(delegate { linkRegister.Visible = true; });
}
精彩评论