temz 2023-03-22 12:24 采纳率: 100%
浏览 124
已结题

委托、事件、Invoke问题

这里是定义委托和事件

        public delegate void MyEvent(string ReceiveMsg);//定义一个委托,用来将接收数据传出去
        public event MyEvent HaveYourMsg;

但是下面用HaveYourMsg的Invoke是怎么回事,Invoke是哪里来的干什么用,为什么能用HaveYourMsg调用呢?

HaveYourMsg.Invoke(Encoding.UTF8.GetString(arrserverrecmsg, 0, length));
HaveYourMsg.Invoke("警告:您的连接已断开!!!");

在form1类中下面这个方法是怎么调用的?

        private void HaveMyMsg(string Msg)
        {
            //使用内联委托处理多线程调用窗体控件的问题
            this.Invoke(new Deal(() =>
            {
                textBox1.Text += Msg + "\r\n";
            }));
        }

全部代码
关于socket的一个类

class SocketTest
    {
        private Socket MySocket;
        //开启一个线程循环执行接收方法来实时接收数据
        private Thread ReceiveThread;
        public delegate void MyEvent(string ReceiveMsg);//定义一个委托,用来将接收数据传出去
        public event MyEvent HaveYourMsg;
        //用于客户端连接服务端
        public bool Connect(IPAddress iP, int port)
        {
            try
            {
                MySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint endPoint = new IPEndPoint(iP, port);
                MySocket.Connect(endPoint);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public bool Send(string str)
        {
            try
            {
                byte[] arrsendmsg = Encoding.UTF8.GetBytes(str);
                if (MySocket.Send(arrsendmsg) != arrsendmsg.Length)
                    return false;
                return true;
            }
            catch
            {
                return false;
            }
        }

        public void recmsg()
        {
            while (true)
            {

                try
                {
                    byte[] arrserverrecmsg = new byte[1024];
                    int length = MySocket.Receive(arrserverrecmsg);
                    if (length > 0)
                    {
                        HaveYourMsg.Invoke(Encoding.UTF8.GetString(arrserverrecmsg, 0, length));
                    }
                }
                catch
                {
                    HaveYourMsg.Invoke("警告:您的连接已断开!!!");
                    return;
                }
                Thread.Sleep(200);
            }
        }

        public void StartReceive()
        {
            ReceiveThread = new Thread(recmsg);
            ReceiveThread.IsBackground = true;
            ReceiveThread.Start();
        }

        public void CloseSocket()
        {
            //如果接收线程正在执行那么先关闭线程在关闭socket
            if (ReceiveThread.ThreadState == ThreadState.Running)
                ReceiveThread.Abort();
            MySocket.Close();
        }
    }

form1类

 public partial class Form1 : Form
    {
        private delegate void Deal();
        public Form1()
        {
            InitializeComponent();
        }

        SocketTest socketTest;
        private void Form1_Load(object sender, EventArgs e)
        {
            socketTest = new SocketTest();
            if (!socketTest.Connect(IPAddress.Parse("127.0.0.1"), 20000))
            {
                MessageBox.Show("连接服务端失败,请重试!");
            }
            //绑定事件接收函数,当有消息时会触发该函数
            socketTest.HaveYourMsg += new SocketTest.MyEvent(HaveMyMsg);
            socketTest.StartReceive();
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            if (textBox2.Text.Length <= 0)
            {
                MessageBox.Show("不允许发送空内容");
                return;
            }
            if (!socketTest.Send(textBox2.Text))
            {
                MessageBox.Show("发送失败了");
                return;
            }
            textBox2.Clear();
        }
        private void HaveMyMsg(string Msg)
        {
            //使用内联委托处理多线程调用窗体控件的问题
            this.Invoke(new Deal(() =>
            {
                textBox1.Text += Msg + "\r\n";
            }));
        }
    }

  • 写回答

8条回答 默认 最新

  • 极客智能体-在线 2023-03-23 00:10
    关注

    以下答案由GPT-3.5大模型与博主波罗歌共同编写:
    在这个代码中,定义了一个委托类型 MyEvent,它可以传输字符串类型的参数。接下来使用关键字 event 创建了一个事件 HaveYourMsg,这个事件对应的委托类型是 MyEvent。

    public delegate void MyEvent(string ReceiveMsg);
    public event MyEvent HaveYourMsg;
    

    当需要在类中注册、注销事件以及在类外部触发事件时,需要使用三个内置的方法:add、remove、invoke。

    在这个代码中,MyEvent 对应的事件是 HaveYourMsg,Invoke 是 MyEvent 的一个方法,所以可以使用 HaveYourMsg.Invoke 间接调用 MyEvent 中的 Invoke 方法。

    HaveYourMsg.Invoke(Encoding.UTF8.GetString(arrserverrecmsg, 0, length));
    HaveYourMsg.Invoke("警告:您的连接已断开!!!");
    

    在类定义中,还定义了一个用于处理事件的方法:

    private void HaveMyMsg(string Msg)
    {
        this.Invoke(new Deal(() =>
        {
            textBox1.Text += Msg + "\r\n";
        }));
    }
    

    在这个方法中,使用了委托类型 Deal,它是一个无参、无返回值的委托类型。在 this.Invoke 中的 lambda 表达式使用委托类型 Deal 来更新 TextBox 中的文本。

    最后,在 Form1 类的构造函数中,将事件 HaveYourMsg 注册到了 HaveMyMsg 方法中。

    socketTest.HaveYourMsg += new SocketTest.MyEvent(HaveMyMsg);
    

    在这行代码中,使用了 += 运算符将 HaveYourMsg 和 HaveMyMsg 关联起来成为事件处理函数。

    关于委托、事件、Invoke 的更多详细信息,可以参考以下链接:

    • .NET 委托和事件详解
    • .NET 事件、委托和 Lambda 表达式的使用方式以及异步的基本知识
      如果我的回答解决了您的问题,请采纳!
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(7条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 3月27日
  • 已采纳回答 3月23日
  • 创建了问题 3月22日

悬赏问题

  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测