各位大侠好本菜鸟在写 socket作业的时候遇到了一个很奇怪的问题,描述如下:背景:
1、要求实现用户端和服务器端,服务器端能检测用户名密码,能echo用户端发送的文本信息
2、选择使用C#实现要求,服务端基于一个窗体类进行编写,由于UI在执行函数的时候会假死,所以选择新创建一个进程,通过跨线程修改主窗体中的label来达成显示信息的目的;
3、进行研究性编写的时候,遇到跨线程调用的问题,查阅MSDN得知可用代理解决,但是编写了代理之后,第一次跨线程修改可以成功,但是第二次调用代理进行跨线程修改时程序卡死,包括UI也不能动了;
4、当3的情况出现以后,我试着改用CheckForIllegalCrossThreadCalls = false;然后直接用this.label_test_display.Text = textBuffer;来进行修改,同样出现了第一次执行正常第二次执行卡死的问题,将label改成textBox问题依旧;作业要交不上了,求各位大侠帮帮小弟吧,感激不尽!!!!附:服务器端代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;namespace WindowsFormsApplication2
{
    public partial class Test_Sever : Form
    {
        Socket server;
        delegate void CrossSetText(string text);//为甚么第二次就不能用了?
        string textBuffer;        private BackgroundWorker bkw1;        private void bkw1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if(textBuffer!=null)
                this.label_test_display.Text += textBuffer;
        }        public Test_Sever()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;        }             private void appendText1(string text)
        {
            if (this.label_test_display.InvokeRequired)
            {
                CrossSetText set = new CrossSetText(appendText1);
                this.Invoke(set, new object[] { text });
            }
            else
            {
                this.label_test_display.Text += text;
            }
        }        public void Show2()
        {
            //Show();
            server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ipend = new IPEndPoint(IPAddress.Any, 44444);            server.Bind(ipend);
            server.Listen(10);
            while (true)
            {
                textBuffer = "/n等待连接/n";
                this.label_test_display.Text += textBuffer;              //  this.backgroundWorker1.RunWorkerAsync();
                Socket client = server.Accept();                IPEndPoint clipos = (IPEndPoint)client.RemoteEndPoint;
                string temp = clipos.Address + ":" + clipos.Port + "已连接\n";
            //    appendText1(temp);                textBuffer = temp;
              //  this.backgroundWorker1.RunWorkerAsync();
                this.label_test_display.Text = textBuffer;                Console.WriteLine(temp);
                byte[] data = new byte[1024];                client.Receive(data,1024,SocketFlags.None);                String content = Encoding.UTF8.GetString(data);                textBuffer = content;
               // this.backgroundWorker1.RunWorkerAsync();
                //appendText1(content);
                this.label_test_display.Text = textBuffer;                byte[] sendbuffer = Encoding.UTF8.GetBytes("ACCESS GRANTED");
                client.Send(sendbuffer,sendbuffer.Length,SocketFlags.None);
            }
        }        private void button1_Click(object sender, EventArgs e)
        {
             new Thread(new ThreadStart(Show2)).Start();
           /* server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ipend = new IPEndPoint(IPAddress.Any, 27019);            server.Bind(ipend);
            server.Listen(10);            label_test_display.Text = "等待连接/n";
            Socket client = server.Accept();            IPEndPoint clipos = (IPEndPoint)client.RemoteEndPoint;
            label_test_display.Text += clipos.Address + ":" + clipos.Port + "已连接\n";
            byte[] data = new byte[1024];            client.Receive(data);            String content = Encoding.UTF8.GetString(data);            label_test_display.Text += content;            client.Send(Encoding.UTF8.GetBytes("ACCESS GRANTED"));*/
        }        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {        }
        private void backgroundWorker1_RunWorkerCompleted(
            object sender,
            RunWorkerCompletedEventArgs e)
        {
            if (textBuffer != null)
                this.label_test_display.Text += textBuffer;
        }    }
}

解决方案 »

  1.   

    不要使用CheckForIllegalCrossThreadCalls 
    用委托实现。
            private delegate void Settext(TextBox obj, string txt);
            private void settext(TextBox obj, string txt)
            {
                obj.Text = txt;
            }线程中    Invoke(settext, new object[] { textBox1, "你的内容!" });
      

  2.   

    不要使用CheckForIllegalCrossThreadCalls
    用Control.Invoke()或Form.Invoke()//其实一样的……
    记得先用invokerequired判断。这样就不必考虑跨线程访问控件的问题了。
    封装成2个扩展方法很好用。以前百度的……static public void UiThread(this Form form, Action action)
            {
                if (form.InvokeRequired)
                {
                    form.Invoke(action);
                    return;
                }
                action.Invoke();
            }        static public void UiThread(this Control c, Action action)
            {
                if (c.InvokeRequired)
                {
                    c.Invoke(action);
                    return;
                }
                action.Invoke();
            }
    调用:
     UiThreadMsg.UiThread(this, () =>
                {
                    picBox.Image = imageList1.Images["logoico_offline.ico"];
                });
      

  3.   

     private void button1_Click(object sender, EventArgs e)
            {
                 new Thread(new ThreadStart(Show2)).Start();
               /* server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint ipend = new IPEndPoint(IPAddress.Any, 27019);            server.Bind(ipend);
                server.Listen(10);            label_test_display.Text = "等待连接/n";
                Socket client = server.Accept();  <---这里是会让线程挂起的,也就是造成UI假死的情况            IPEndPoint clipos = (IPEndPoint)client.RemoteEndPoint;
                label_test_display.Text += clipos.Address + ":" + clipos.Port + "已连接\n";
                byte[] data = new byte[1024];            client.Receive(data); <---这里是会让线程挂起的,也就是造成UI假死的情况            String content = Encoding.UTF8.GetString(data);            label_test_display.Text += content;            client.Send(Encoding.UTF8.GetBytes("ACCESS GRANTED"));*/
            }
    所以最好这一部份也要用线程或用Socket的异步处理
    label_test_display.Text = "等待连接/n";
                Socket client = server.Accept();  <---这里是会让线程挂起的,也就是造成UI假死的情况            IPEndPoint clipos = (IPEndPoint)client.RemoteEndPoint;
                label_test_display.Text += clipos.Address + ":" + clipos.Port + "已连接\n";
                byte[] data = new byte[1024];            client.Receive(data); <---这里是会让线程挂起的,也就是造成UI假死的情况            String content = Encoding.UTF8.GetString(data);            label_test_display.Text += content;            client.Send(Encoding.UTF8.GetBytes("ACCESS GRANTED"));*/