C#/异步网络和GUI之间的通信

时间:2011-06-12 01:10:20

标签: c# .net winforms multithreading parallel-processing

我在C#.NET中使用TcpClientTcpListener类进行异步网络。 我使用WinForms作为GUI。

每当我从远程计算机接收数据时,操作都在不同的底层线程上完成。

我需要做的是在收到网络响应时更新应用程序的GUI。

// 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)
}

我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:3)

在Winforms中,您需要使用Control.Invoke Method (Delegate)来确保在UI线程中更新控件。

示例:

public static void PerformInvoke(Control ctrl, Action action)
{
    if (ctrl.InvokeRequired)
        ctrl.Invoke(action);
    else
        action();
}

用法:

PerformInvoke(textBox1, () => { textBox1.Text = "test"; });

答案 1 :(得分:2)

在GUI写入函数中如下:

 public void f() {

        MethodInvoker method = () => {
            // body your function
        };

        if ( InvokeRequired ) {
            Invoke( method );  // or BeginInvoke(method) if you want to do this asynchrous
        } else {
            method();
        }
    }

如果你在其他线程中调用此函数,它将在GUI线程中调用

答案 2 :(得分:0)

我在Alex建议的代码中添加了一个扩展方法。它变得更好!

// 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; });
}