首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

C# C/S多窗体程序 showdialog后堵塞

2013-09-17 
C#C/S多窗体程序showdialog后阻塞登陆成功后,new了一个新窗体,并且需要在新窗体中与服务器沟通,现在可以把

C# C/S多窗体程序 showdialog后阻塞
登陆成功后,new了一个新窗体,并且需要在新窗体中与服务器沟通,现在可以把请求发给服务器,客户端这边执行到showdialog后就阻塞了,不能收到服务器发过来的命令了,客户端这边只有一个线程是用来与服务器沟通,客户端这边是不是需要一个新线程了执行showdialog方法?我的程序里有多个窗体,那是不是每执行一次showdialog方法,就需要创建一个新的线程呢?

contactWithServer = new ContactWithServer(this, user);
Thread clientcontactserverThread = new Thread(new ThreadStart(contactWithServer.ReceiveMsg));
            clientcontactserverThread.Start();
 


   
public void ReceiveMsg()
        {
            while (true)
            {
                lock (this)
                {
                    // 调用接收回调函数
                    IAsyncResult iar = udpReceiveClient.BeginReceive(new AsyncCallback(ReceiveCallback), udpReceiveState);
                    receiveDone.WaitOne();
                    Thread.Sleep(100);
                }
            }
        }
        private void ReceiveCallback(IAsyncResult iar)
        {
            UdpState udpReceiveState = iar.AsyncState as UdpState;
            if (iar.IsCompleted)
            {
                data = udpReceiveState.udpClient.EndReceive(iar, ref udpReceiveState.ipEndPoint);
                if (data.Length < 20)                       //只有命令
                        commandStr = Encoding.ASCII.GetString(data);


                    else                                       //既有命令又有数据
                    {
                        int i = 0;
                        ///取出命令
                        for (i = 0; i < leng; i++)
                        {
                            if (Convert.ToInt32(data[i]) == 0)    //寻找请求中的有效字符的最终位置
                                break;
                        }
                        byte[] cmdbyte = new byte[i];
                        for (int k = 0; k < i; k++)
                        {
                            cmdbyte[k] = data[k];
                        }
                        commandStr = Encoding.ASCII.GetString(cmdbyte);                    


                    }
                    MessageBox.Show(commandStr, "来自服务器的命令!");
                    handleMsg(commandStr);                
                Thread.Sleep(100);
                receiveDone.Set();               
            }
        }
        private void handleMsg(string commandStr)
        {
            switch (commandStr)
            {
                case "LoginSuccess":
                    {
                        登陆.LoginFormDelegate closeDelegate = new 登陆.LoginFormDelegate(loginFormAction);
                        loginForm.Invoke(closeDelegate, new String[] { "close" });
                        loginForm.isFirst = false;         //客户端已登陆成功,下次发给服务器的消息从另一端口发出
                        frm = new 申请及扫描(user, this);
                        [color=#000000]frm.ShowDialog();[/color]
                    }
                    break;
                case "LoginFail":


                    {
                        MessageBox.Show("用户名或者密码错误");
                        登陆.LoginFormDelegate clearDelegate = new 登陆.LoginFormDelegate(loginFormAction);
                        loginForm.Invoke(clearDelegate, new String[] { "clear" });
                    }
                    break;
                case "ReFreshData":
                    ///取出数据
                    buff = new byte[data.Length - leng];
                    for (int j = 0; j < data.Length - leng; j++)
                        buff[j] = data[leng + j];
                    memStream = new MemoryStream(buff);
                    memStream.Seek(0, SeekOrigin.Begin);
                    memStream.Flush();
                    DataTable dt = new DataTable();
                    dt = (DataTable)formatter.Deserialize(memStream);
                    memStream.Close();
                    MessageBox.Show("收到服务器的命令");


                    break;
            }
        }


[解决办法]
不对,仔细读了下代码,发现你在线程里用了 Dialog,那必然阻塞啊,线程去等 Dialog 的返回值了,当然就停了

线程中应该仅仅只对收到的数据进行处理,而不要参与到 UI 方面的问题(类似显示,弹出提示框,等等),线程的功能要单一,不应该去管理控件和显示

我觉得,你应该有线程去管理一个公用变量,然后由主进程去检查,公用变量中是否有message,然后显示它

热点排行