1. 异步的回调和状态参数
2. 异步等待
3. 获取异步的返回值
private void AsynicAdvanced_Click(object sender, EventArgs e) { Console.WriteLine("****************AsynicAdvancedButton_Click Begin******************"); { string threadname = string.Format("OneThread"); Action<string> threadDelegate = UseTimeMethod; //委托是异步多线程的基础 // BeginInvoke的倒数第二个参数是回调参数,这个参数是AsyncCallback类型,该类型是一个委托: // public delegate void AsyncCallback(IAsyncResult ar) // BeginInvoke完成后会返回一个IAsyncResult类型的结果,这个结果又作为回调方法的参数 // 回调的作用就是:异步结束后你想做的操作 IAsyncResult Iresult = null; AsyncCallback callback = t => { Console.WriteLine("BeginInvoke的状态值是{0}", t.AsyncState); //这个是状态参数,object类型,这里简单的传了一个string类型 Console.WriteLine("BeginInvoke是否完成:{0} ", t.IsCompleted); //这个表示异步操作是否完成 Console.WriteLine("回调参数的类型是否等同于Iresult:{0}", t.Equals(Iresult)); // IAsyncResult是beginInvoke异步执行返回值的类型 Console.WriteLine("这是异步回调"); }; Iresult = threadDelegate.BeginInvoke(threadname, callback, "yoyo"); // 现在希望异步执行完后再执行之后的语句。有两种方式: // 1. 做一个进度条 // 2. EndInvoke() //进度条 while (!Iresult.IsCompleted) //异步没完成,执行循环 { for (int i = 1; i < 10; i++) { Console.WriteLine("异步线程以完成了{0}%", i * 10); Thread.Sleep(300); //进度条基本都是假的,因为在前一节课算过一个异步完成大概是3秒 } } // 用EndInvoke(); threadDelegate.EndInvoke(Iresult); // EndInvoke需要一个参数,这个参数就是BeginInvoke的返回值 } //如果异步要完成的方法是带返回值的,需要怎么显示这个返回值,先创建一个带返回值的方法 { Func<string, int> ThreadDelegate = WithReturnUseTimeMethod; IAsyncResult Iresult = null; Iresult = ThreadDelegate.BeginInvoke("AsyncThread", null, null); int Asyncresult = 0; Asyncresult =ThreadDelegate.EndInvoke(Iresult); //这个结果就是异步调用方法的返回值 Console.WriteLine("异步调用方法的返回值为{0}", Asyncresult); } Console.WriteLine("****************AsynicAdvancedButton_Click End********************"); } //定义一个耗时的方法 public void UseTimeMethod(string threadname)//不带返回值 { Console.WriteLine("{0} {1} start ,线程id={2}", DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss.fff"), threadname, Thread.CurrentThread.ManagedThreadId); int icount = 0; for (int i = 0; i < 1000000000; i++) { icount = i; } Console.WriteLine("{0} {1} end ,线程id={2},Result={3}", DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss.fff"), threadname, Thread.CurrentThread.ManagedThreadId, icount); } public int WithReturnUseTimeMethod(string threadname)//带返回值 { Console.WriteLine("{0} {1} start ,线程id={2}", DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss.fff"), threadname, Thread.CurrentThread.ManagedThreadId); int icount = 0; for (int i = 0; i < 1000000000; i++) { icount = i; } Console.WriteLine("{0} {1} end ,线程id={2},Result={3}", DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss.fff"), threadname, Thread.CurrentThread.ManagedThreadId, icount); return icount; }
结果