这里是定义委托和事件
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";
}));
}
}
以下答案由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 的更多详细信息,可以参考以下链接:
基于最新版ChatGPT4的回答,望采纳!!!有其他问题也可以询问我哦💕(最新版更智能,功能更加强大):
从给定的代码中,我们可以看到有关委托和事件的定义:
public delegate void MyEvent(string ReceiveMsg); // 定义一个委托,用来将接收数据传出去
public event MyEvent HaveYourMsg;
在这里,MyEvent是一个委托,它定义了一个接受一个字符串参数的方法签名。HaveYourMsg是一个事件,它使用MyEvent委托类型。
接下来,我们来看Invoke的使用:
HaveYourMsg.Invoke(Encoding.UTF8.GetString(arrserverrecmsg, 0, length));
HaveYourMsg.Invoke("警告:您的连接已断开!!!");
Invoke是一个方法,用于触发事件。当你调用Invoke方法时,所有订阅了该事件的方法都会被执行。在这个例子中,HaveYourMsg事件被触发,因此所有订阅了HaveYourMsg事件的方法都会执行。
在Form1类中,有一个名为HaveMyMsg的方法,它如何被调用?
private void HaveMyMsg(string Msg)
{
// 使用内联委托处理多线程调用窗体控件的问题
this.Invoke(new Deal(() =>
{
textBox1.Text += Msg + "\r\n";
}));
}
在Form1_Load方法中,HaveMyMsg方法订阅了socketTest.HaveYourMsg事件:
socketTest.HaveYourMsg += new SocketTest.MyEvent(HaveMyMsg);
这意味着当HaveYourMsg事件被触发时,HaveMyMsg方法会被调用。在HaveMyMsg方法内部,使用了this.Invoke方法来处理跨线程调用UI控件的问题。this.Invoke接受一个委托类型参数(这里是Deal),并在UI线程上执行该委托。在这个例子中,textBox1.Text属性在UI线程上被修改。
Invoke 是方法内继承来的,该方法时用来跨线程进行访问和操作所必须的
你这样理解,每个委托都是个对象,对象的构造函数接受一个【函数定义】,然后都有个默认的invoke方法,当你调用invoke方法时,触发你这个对象构造函数接受的【函数】
//定义一个委托
public delegate void MyEvent(string ReceiveMsg);
//用刚定义的委托,定义一个事件,你可以理解为他是委托的一个变化,或者先理解未事件是委托的子类
public event MyEvent HaveYourMsg;
//然后初始化这个事件,初始化时,接受一个【函数定义】HaveMyMsg
socketTest.HaveYourMsg += new SocketTest.MyEvent(HaveMyMsg);
下面是你的函数
private void HaveMyMsg(string Msg)
{
//使用内联委托处理多线程调用窗体控件的问题
this.Invoke(new Deal(() =>
{
textBox1.Text += Msg + "\r\n";
}));
}
然后你调用这个事件
HaveYourMsg.Invoke("警告:您的连接已断开!!!");
这句话等价于
HaveMyMsg("警告:您的连接已断开!!!");
基于最新版ChatGPT4的回答,望采纳!!!有其他问题也可以询问我哦、”(最新版更智能,功能更加强大)
在您提供的代码中,HaveYourMsg
是一个事件,其类型为 MyEvent
委托。当调用 HaveYourMsg.Invoke
时,实际上是在调用与事件关联的所有订阅者(在这个例子中,是 HaveMyMsg
方法)。
Invoke
是事件的一个方法,它用于触发事件并将参数传递给事件的订阅者。在这个例子中,HaveYourMsg.Invoke
会调用 HaveMyMsg
方法,并传递一个字符串参数。
关于 HaveMyMsg
方法的调用,它是通过订阅 socketTest.HaveYourMsg
事件实现的。在 Form1_Load
方法中,有以下一行代码:
socketTest.HaveYourMsg += new SocketTest.MyEvent(HaveMyMsg);
这行代码将 HaveMyMsg
方法订阅到 socketTest.HaveYourMsg
事件。因此,当 socketTest
实例中的 HaveYourMsg
事件被触发时,HaveMyMsg
方法将被自动调用。
在 HaveMyMsg
方法中,使用了 Invoke
方法处理多线程调用窗体控件的问题。Invoke
方法接受一个委托参数(在这里是一个匿名内联委托),并在与窗体关联的线程上执行该委托。这样可以确保在更新 UI 控件(如 textBox1
)时不会出现跨线程操作的问题。
chatGPT别管回答专业不专业,聊天能力是真的强,全是废话
Invoke 其实就是用于执行委托的方法,是每个类的内置对象,是继承自object基类的
基于bing、GPT部分内容和本人思考总结:
什么是markdown?
Markdown是一种轻量级标记语言,它使用简单的标记语法来表示文本的样式和结构,以便于阅读和编写。它可以用于编写文档、博客、电子邮件、论坛帖子等等。
Markdown有哪些优点?
Markdown具有以下优点:
简单易学:Markdown的语法非常简单易懂,只需要几分钟就可以学会。
易读易写:Markdown的语法使得文本看起来更加清晰易读,同时也更加易于书写和编辑。
平台无关性:Markdown可以在各种平台上使用,例如Windows、Mac、Linux等等。
兼容HTML:Markdown可以与HTML语言兼容,可以使用HTML标签来扩展Markdown的功能。
可移植性:Markdown的文本文件可以轻松地转换成HTML、PDF、Word等格式,使得文档更加易于分享和传播。
Markdown的语法有哪些?
Markdown的语法包括以下几种:
标题:使用#符号表示,#的数量表示标题的级别。
段落:用空行来分隔段落。
强调:使用*或_来表示斜体或加粗。
列表:使用数字或符号来表示有序或无序列表。
链接:使用description来表示链接。
图片:使用来表示图片。
引用:使用>来表示引用。
代码:使用`或```来表示代码。
表格:使用|和-来表示表格。
Markdown的编辑器有哪些?
Markdown的编辑器有很多种,包括:
Typora:一款功能强大、界面美观的Markdown编辑器,支持实时预览、自定义主题等功能。
VS Code:一款流行的代码编辑器,支持Markdown扩展,可以实现Markdown的语法高亮、预览等功能。
Atom:一款开源的文本编辑器,支持Markdown语法高亮、预览、自动补全等功能。
Sublime Text:一款轻量级的文本编辑器,支持Markdown语法高亮、预览、自动补全等功能。
Mou:一款Mac上的Markdown编辑器,支持实时预览、自定义样式等功能。