·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> ASP网站建设 >> .Net 异步处理温习

.Net 异步处理温习

作者:佚名      ASP网站建设编辑:admin      更新时间:2022-07-23
这几天,看WF本质论,里面提到了.net的异步处理。由于里面使用的是代码片段,所以有点看不懂。于是下定决心,温习一下.net中的异步处理。

使用C#在.net开发已经有5年了,最初使用.net中的异步处理大约是在4年前。当时,只是为了实现要求的功能,没有详细研究。这也难怪看WF时会头晕(基础不牢的后果呀)。

首先,我们分析一下异步处理的环境

需要在当前线程中获取返回值
不需要在当前线程中获取返回值,但是仍然需要对返回值做处理
对于第1中情况,还可以继续细分

在当前线程中启动线程T,然后继续执行当前线程中的其它任务,最后在当前线程中获取T的返回值
在当前线程中启动线程T,然后继续执行当前线程中的其它任务R1,等待T执行完成,当T执行完成后,继续执行当前线程中的其它任务R2,最后获取T的返回值
在当前线程中启动线程T,只要T在执行就执行任务R,最后获取T的返回值
下面,我将一一给出例子:

1.1 在当前线程中启动线程T,然后继续执行当前线程中的其它任务,最后在当前线程中获取T的返回值
view sourcePRint?01 using System;  

02 using System.Collections.Generic;  

03 using System.Linq;  

04 using System.Windows.Forms;  

05 using System.Threading;  

06 using System.Runtime.Remoting.Messaging;  

07 namespace FirstWF  

08 {  

09     static class Program  

10     {  

11         /// <summary>  

12         /// The main entry point for the application.  

13         /// </summary>  

14         [STAThread]  

15         static void Main()  

16         {  

17             AsyncFuncDelegate caller = new AsyncFuncDelegate(Func);  

18             Console.WriteLine("Input number please...");  

19             IAsyncResult result = caller.BeginInvoke(Convert.ToInt32(Console.ReadLine()), null, null);  

20             Console.WriteLine("Implement other tasks");  

21             Thread.Sleep(7000);  

22             Console.WriteLine("Implement other tasks end ...");  

23             Console.WriteLine("Get user's input");  

24             Console.WriteLine(caller.EndInvoke(result));  

25             Console.ReadLine();  

26         }  

27         delegate string AsyncFuncDelegate(int userInput);  

28         static string Func(int userInput)  

29         {  

30             Console.WriteLine("Func start to run");  

31             Console.WriteLine("...");  

32             Thread.Sleep(5000);  

33             Console.WriteLine("Func end to run");  

34             return userInput.ToString();  

35         }  

36     }  

37 }

输出结果如下:

Implement other tasks

Func start to run

...

Func end to run

Implement other tasks end ...

Get user's input

56

1.2 在当前线程中启动线程T,然后继续执行当前线程中的其它任务R1,等待T执行完成,当T执行完成后,继续执行当前线程中的其它任务R2,最后获取T的返回值
view sourceprint?01 static void Main()  

02         {  

03             AsyncFuncDelegate caller = new AsyncFuncDelegate(Func);  

04             Console.WriteLine("Input number please...");  

05             IAsyncResult result = caller.BeginInvoke(Convert.ToInt32(Console.ReadLine()), null, null);  

06             Console.WriteLine("Implement task 1");  

07             result.AsyncWaitHandle.WaitOne();  

08             result.AsyncWaitHandle.Close();  

09             Console.WriteLine("Implment task 2");  

10             Console.WriteLine("Get user's input");  

11             Console.WriteLine(caller.EndInvoke(result));  

12             Console.ReadLine();  

13         }

输出结果如下:

Input number please...

25

Implement task 1

Func start to run

...

Func end to run

Implment task 2

Get user's input

25



1.3 在当前线程中启动线程T,只要T在执行就执行任务R,最后获取T的返回值
view sourceprint?01 [STAThread]  

02         static void Main()  

03         {  

04             AsyncFuncDelegate caller = new AsyncFuncDelegate(Func);  

05             Console.WriteLine("Input number please...");  

06             IAsyncResult result = caller.BeginInvoke(Convert.ToInt32(Console.ReadLine()), null, null);  

07             while (!result.IsCompleted)  

08             {  

09                 Thread.Sleep(1000);  

10                 Console.Write(">");  

11             }  

12             Console.WriteLine("");  

13             Console.WriteLine("Implement other task2");  

14             Console.WriteLine("Get user's input");  

15             Console.WriteLine(caller.EndInvoke(result));  

16             Console.ReadLine();  

17         }

输出结果如下:

Func start to run

...

>>>>>Func end to run

>

Implement other task2

Get user's input

23



2 不需要在当前线程中获取返回值,但是仍然需要对返回值做处理


view sourceprint?01 using System;  

02 using System.Collections.Generic;  

03 using System.Linq;  

04 using System.Windows.Forms;  

05 using System.Threading;  

06 using System.Runtime.Remoting.Messaging;  

07 namespace FirstWF  

08 {  

09     static class Program  

10     {  

11         /// <summary>  

12         /// The main entry point for the application.  

13         /// </summary>  

14         [STAThread]  

15         static void Main()  

16         {  

17             AsyncFuncDelegate caller = new AsyncFuncDelegate(Func);  

18             Console.WriteLine("Input number please...");  

19             caller.BeginInvoke(Convert.ToInt32(Console.ReadLine()), new AsyncCallback(CallBackFunc), "Message from Main thread.");  

20             Console.WriteLine("Main thread ends");  

21             Console.ReadLine();  

22         }  

23         delegate string AsyncFuncDelegate(int userInput);  

24         static string Func(int userInput)  

25         {  

26             Console.WriteLine("Func start to run");  

27             Console.WriteLine("...");  

28             Thread.Sleep(5000);  

29             Console.WriteLine("Func end to run");  

30             return userInput.ToString();  

31         }  

32         static void CallBackFunc(IAsyncResult ar)  

33         {  

34             AsyncResult result = ar as AsyncResult;  

35             string inputMessage = result.AsyncState as string;  

36             AsyncFuncDelegate caller = result.AsyncDelegate as AsyncFuncDelegate;  

37             Console.WriteLine("call back starts");  

38             Console.WriteLine(inputMessage);  

39             Console.WriteLine("The input number is : " + caller.EndInvoke(ar));  

40             Console.WriteLine("call back ends");  

41         }  

42     }  

43 }



输出结果如下:

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可以保证异步调用被正常结束,使代码更加健康。

异步调用,可以使代码具有更高的执行效率,但是在异步调用时,应该有一个健康的使用习惯。