Code Bye

窗体之间事件委托通讯的问题

现在有一个主窗体收到数据,通过事件机制将主窗体的数据发送给子窗体,当子窗体关闭后,父窗体在事件触发时会发生什么情况?
在下面的例子中,当form2被关闭后,再点击from1上的button,委托函数会怎么样处理?当form2关闭时,能否需要卸载setlabel中注册的事件?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public delegate void setLabel(string str);//事件产生者先定义委托
        public event setLabel setlabel;//事件产生者定义事件
        public Form1()
        {
            InitializeComponent();
            Form2 frm2 = new Form2();
            setlabel+= new setLabel(frm2.setLabel);//在事件产生者中或第三方类中、或处理类中注册事件的处理函数
            frm2.Show();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            if (setlabel!= null)//时间产生者来触发事件
            {
                setlabel("abc");
            }
        }
    }
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }
        public void setLabel(string str)
        {
            this.label1.Text = str;
        }
    }
}
解决方案

40

你这个事件毫无意义。一个对象它本人触发事件,本人捕获事件,捣什么乱啊?它直接调用想要执行的方法(frm2.setLabel)不就行了嘛,还触发什么事件?
想把这个问题放在一边,假设你的代码是合理的,来看看它意味着什么。
你的代码中,form2永远也不会被 GC 释放,也就是说虽然 form2 可能将来再也“看不见了”,但是 frm2.setLabel 一直会被“默默地”反复执行。虽然 form2 上的 label1 控件根本看不见了,但是它还是会被不断地更新 Text。
这就是所谓 .net 中的“内存泄漏”问题。这种泄露不是系统开发工具太烂而造成的,是编程者的流程造成的。你把一个提前要扔掉的对象(form2引用它)指定给一个不释放的对象(Form1实例自身)去引用,这就造成无用的对象垃圾不能被 GC 回收,而且还一直在占用系统资源且在背后执行。
总的来说,你从一开始的程序设计思路很乱。看不出你在 Form1 中为什么要捕获本人的事件?!一个错误就引起了更多的乱。

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明窗体之间事件委托通讯的问题