这几天,看WF本质论,里面提到了.net的异步处理。由于里面使用的是代码片段,所以有点看不懂。于是下定决心,温习一下.net中的异步处理。
使用C#在.net开发已经有5年了,最初使用.net中的异步处理大约是在4年前。当时,只是为了实现要求的功能,没有详细研究。这也难怪看WF时会头晕(基础不牢的后果呀)。
首先,我们分析一下异步处理的环境
对于第1中情况,还可以继续细分
下面,我将一一给出例子:
using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using System.Threading; using System.Runtime.Remoting.Messaging; namespace FirstWF { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { AsyncFuncDelegate caller = new AsyncFuncDelegate(Func); Console.WriteLine("Input number please..."); IAsyncResult result = caller.BeginInvoke(Convert.ToInt32(Console.ReadLine()), null, null); Console.WriteLine("Implement other tasks"); Thread.Sleep(7000); Console.WriteLine("Implement other tasks end ..."); Console.WriteLine("Get user's input"); Console.WriteLine(caller.EndInvoke(result)); Console.ReadLine(); } delegate string AsyncFuncDelegate(int userInput); static string Func(int userInput) { Console.WriteLine("Func start to run"); Console.WriteLine("..."); Thread.Sleep(5000); Console.WriteLine("Func end to run"); return userInput.ToString(); } } }
输出结果如下:
Implement other tasks
Func start to run
...
Func end to run
Implement other tasks end ...
Get user's input
56
static void Main() { AsyncFuncDelegate caller = new AsyncFuncDelegate(Func); Console.WriteLine("Input number please..."); IAsyncResult result = caller.BeginInvoke(Convert.ToInt32(Console.ReadLine()), null, null); Console.WriteLine("Implement task 1"); result.AsyncWaitHandle.WaitOne(); result.AsyncWaitHandle.Close(); Console.WriteLine("Implment task 2"); Console.WriteLine("Get user's input"); Console.WriteLine(caller.EndInvoke(result)); Console.ReadLine(); }
输出结果如下:
Input number please...
25
Implement task 1
Func start to run
...
Func end to run
Implment task 2
Get user's input
25
[STAThread] static void Main() { AsyncFuncDelegate caller = new AsyncFuncDelegate(Func); Console.WriteLine("Input number please..."); IAsyncResult result = caller.BeginInvoke(Convert.ToInt32(Console.ReadLine()), null, null); while (!result.IsCompleted) { Thread.Sleep(1000); Console.Write(">"); } Console.WriteLine(""); Console.WriteLine("Implement other task2"); Console.WriteLine("Get user's input"); Console.WriteLine(caller.EndInvoke(result)); Console.ReadLine(); }
输出结果如下:
Func start to run
...
>>>>>Func end to run
>
Implement other task2
Get user's input
23
using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using System.Threading; using System.Runtime.Remoting.Messaging; namespace FirstWF { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { AsyncFuncDelegate caller = new AsyncFuncDelegate(Func); Console.WriteLine("Input number please..."); caller.BeginInvoke(Convert.ToInt32(Console.ReadLine()), new AsyncCallback(CallBackFunc), "Message from Main thread."); Console.WriteLine("Main thread ends"); Console.ReadLine(); } delegate string AsyncFuncDelegate(int userInput); static string Func(int userInput) { Console.WriteLine("Func start to run"); Console.WriteLine("..."); Thread.Sleep(5000); Console.WriteLine("Func end to run"); return userInput.ToString(); } static void CallBackFunc(IAsyncResult ar) { AsyncResult result = ar as AsyncResult; string inputMessage = result.AsyncState as string; AsyncFuncDelegate caller = result.AsyncDelegate as AsyncFuncDelegate; Console.WriteLine("call back starts"); Console.WriteLine(inputMessage); Console.WriteLine("The input number is : " + caller.EndInvoke(ar)); Console.WriteLine("call back ends"); } } }
输出结果如下:
Input number please...
23
Main thread ends
Func start to run
...
Func end to run
call back starts
Message from Main thread.
The input number is : 23
call back ends
记得以前的代码,写的都不是很好。虽然call.BeginInvoke可以开始异步调用,但几乎就没有使用过EndInvoke。EndInvoke可以保证异步调用被正常结束,使代码更加健康。
异步调用,可以使代码具有更高的执行效率,但是在异步调用时,应该有一个健康的使用习惯。