委托实现多窗体传值

主窗体的代码:

public partial class FrmMain : Form
{
//[3] 创建委托对象(委托对象能够将委托和具体方法关联)
public ShowCounterDelegate msgSender;


public FrmMain()
{
InitializeComponent();
//创建从窗体对象
FrmOther01 objFrm01 = new FrmOther01();
FrmOther02 objFrm02 = new FrmOther02();
FrmOther03 objFrm03 = new FrmOther03();

//4.将委托变量和具体方法关联
this.msgSender += objFrm01.Receiver;
this.msgSender += objFrm02.Receiver;
this.msgSender += objFrm03.Receiver;

//显示三个从窗体
objFrm01.Show();
objFrm02.Show();
objFrm03.Show();
}
private int counter = 0;
/// <summary>
/// 发消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnClick_Click(object sender, EventArgs e)
{
counter++;
//msgSender(counter.ToString()); //5.调用委托变量传递信息
msgSender.Invoke(counter.ToString());
}
/// <summary>
/// 复位
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnReset_Click(object sender, EventArgs e)
{
counter = 0;
msgSender("0");
}
}

//1.声明委托
public delegate void ShowCounterDelegate(string counter);

 子窗体的代码:

//2.根据委托定义方法(接收委托传递的信息)
public void Receiver(string counter)
{
this.IblCounter.Text = counter;
}
//2.根据委托定义方法(接收委托传递的信息)
public void Receiver(string counter)
{
this.IblCounter.Text = counter;
}
//2.根据委托定义方法(接收委托传递的信息)
public void Receiver(string counter)
{
this.IblCounter.Text = counter;
}

 同步委托和异步委托

public partial class FrmMain : Form
{
public FrmMain()
{
InitializeComponent();
}


private void btnExe1_Click(object sender, EventArgs e)
{
this.lblCount1.Text = ExectueTask1(10).ToString();
this.lblCount2.Text = ExectueTask2(10).ToString();
}



//2.根据委托定义实现的方法
private int ExectueTask1(int num)
{
System.Threading.Thread.Sleep(5000);//延迟5秒
return num * num;
}

private int ExectueTask2(int num)
{
return num * num;
}
private void btnExe2_Click(object sender, EventArgs e)
{
MyCalculator objMyCal = ExectueTask1; //创建委托变量,代表方法1

//通过委托异步调用方法
//委托类型的 BeginInvoke(<输入和输出参数>,AsyncCallback callback,object asyncState)方法:异步调用的核心
//第一个方法10,表示委托对应的实参
//第二个参数callback:回调函数,表示异步调用后自动调用的函数
//第三个参数asyncState,用于向回调函数提供参数信息
//返回值 IAsyncResult-->异步操作状态接口,封住了异步执行的参数


//异步调用任务
IAsyncResult result = objMyCal.BeginInvoke(10,null,null);
this.lblCount1.Text = "正在计算请稍等。。。";


//同步执行其他任务
this.lblCount2.Text = ExectueTask2(10).ToString();

//获取异步执行的结果
int res = objMyCal.EndInvoke(result);
//委托类型的EndInvoke() 方法:借助于IAsyncResult接口对象,不断的查询异步调用是否结束
//该方法知道异步调用的方法所有参数,所以,异步调用完毕后,取出异步调用的结果作为返回值
this.lblCount1.Text = res.ToString();
}


//1.定义一个委托
public delegate int MyCalculator(int num);
}

 异步委托:

public partial class FrmMain : Form
{
public FrmMain()
{
InitializeComponent();
//初始化委托变量
this.objMyCal = new MyCalculator(ExecuteTask);

//Lambda表达式
//this.objMyCal = (num, ms) =>
// {
// System.Threading.Thread.Sleep(ms);
// return num * num;
// };
}
//1.声明一个委托 延迟的秒数
public delegate int MyCalculator(int num, int ms); //延迟的秒数

//2.根据委托定义方法:返回一个数的平方
private int ExecuteTask(int num, int ms)
{
System.Threading.Thread.Sleep(ms);
return num * num;
}

//3.创建委托变量
MyCalculator objMyCal = null;


//同时执行多个任务
private void btnExec_Click(object sender, EventArgs e)
{

//产生10个任务
for (int i = 1; i < 11; i++)
{
//开始异步执行,并封装异步函数
objMyCal.BeginInvoke(10 * i, 1000 * i, MyCallBack, i);
//最后一个参数i给回调函数AsyncState赋值,这个字段是object类型,如果数据很多,可以传递集合或者类和结构
}
}

//5.编写回调函数
private void MyCallBack(IAsyncResult result)
{
int res= objMyCal.EndInvoke(result);

//异步显示结果形式:第一个的计算结果:100
Console.WriteLine("第{0}个计算结果:{1}",result.AsyncState.ToString(),res);
}
//异步编程总结
//1.异步编程是建立在委托基础上的编程方法
//2.异步调用的每个方法都是在独立的线程上执行的。因此,本质上就是一种多线程程序,也可以说是一个“简化的多线程技术”
//3.比较适合在后台运行较为耗时间的《简单任务》,并且要求任务之间是独立的,任务中不要有直接访问可视化控件的内容。
//4.如果后台任务要求必须按照特定顺序执行,或者访问到特定的共享资源,异步编程不太适合,而应该选择多线程开发技术
}