多线程使用AsyncCallback和GUI控件

本文关键字:GUI 控件 AsyncCallback 多线程 | 更新日期: 2023-09-27 18:09:51

多线程编程对我来说是一个全新的概念。我读了很多书,即使有很多例子,我似乎还是弄不明白。我是c#和编程新手。

我有一个winform项目,其中有许多我导入的自定义控件,并将利用许多tcpclient。我试图让每个控件托管在它自己的单独线程上。现在,我正试图得到1控制行为适当与它自己的线程。

我会向你展示我所拥有的,然后接着问一些关于指导的问题。

string asyncServerHolder; // gets the server name from a text_changed event
int asyncPortHolder; // gets the port # from a text_changed event
TcpClient wifiClient = new TcpClient();
private void btnStart_Click(object sender, EventArgs e)
{
 ... // variable initialization, etc.
 ... // XML setup, http POST setup.
 send(postString + XMLString); // Content to send.
}
private void send(string msg)
{
    AsyncCallback callBack = new AsyncCallback(ContentDownload);
    wifiClient.BeginConnect(asyncServerHolder, asyncPortHolder, callBack, wifiClient);
    wifiClient.Client.Send(System.Text.Encoding.ASCII.GetBytes(msg));
}
private void ContentDownload(IAsyncResult result)
{
    if (wifiClient.Connected)
    {
        string response4 = "Connected!!"; //debug msg
        byte[] buff = new byte[1024];
        int i = wifiClient.Client.Receive(buff);
        do
        {
            response1 = System.Text.Encoding.UTF8.GetString(buff, 0, i);
        } while (response1.Length == 0);
        response2 = response1.Substring(9, 3); // pick out status code to be displayed after
        wifiClient.Client.Dispose();
        wifiClient.Close();
    }
}

如果你了解这一点,我打赌你看到了上面的很多问题。现在,我总是在第一次运行这个序列时得到一个异常:

"发送或接收数据的请求被拒绝,因为套接字未连接并且(当使用sendto调用在数据报套接字上发送时)没有提供地址"

为什么会这样?我已经确认我的asyncServerHolder和我的asyncPortHolder是正确的。我的第二次尝试允许我看到response4 = "Connected!!",但我在response1上得到一个空响应。

最后,我想替换我的用户控件,我在一个列表。我只是想优雅地连接,发送我的msg,接收我的响应,然后允许我的表单从tcp客户端的特定控件通知我。我的下一步是连接多个控件。

的一些问题:1)我需要更多的TCP客户端吗?它们应该在一个列表中,并且是我在btnStart_Click时启用的控件的# ?

2)我的控件在我的GUI上,这是否意味着我需要调用,如果我与他们交互?

3)我看到很多使用静态方法的例子。为什么会这样?

提前感谢。欢迎所有批评,请随意批评!

多线程使用AsyncCallback和GUI控件

BeginConnect立即返回。可能是Send运行时还没有建立连接。请确保仅在连接完成后才使用该连接。

if (wifiClient.Connected),如果!Connected呢?你什么都不做。这不是一个有效的错误恢复策略。完全删除这个if

在read循环中,在每次迭代中销毁先前读取的内容。事实上,您根本不能拆分UTF8编码的字符串并分别解码各部分。将所有字节读入某个缓冲区,只有当您接收到所有字节时,才将字节解码为字符串。

    wifiClient.Client.Dispose();
    wifiClient.Close();

迷信的处置模式。wifiClient.Dispose();是发布所有内容的规范方式。

我不太明白你说的"控制"是什么。套接字不是控件。UI控件是单线程的。只能在UI线程中访问它们。

我需要更多TCP客户端吗?

每个连接都需要一个。

也许,你应该使用await的所有阻塞操作。有一些包装器库可以使套接字api与await一起使用。