• .Net 异步处理温习 CQ


    这几天,看WF本质论,里面提到了.net的异步处理。由于里面使用的是代码片段,所以有点看不懂。于是下定决心,温习一下.net中的异步处理。

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

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

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

    对于第1中情况,还可以继续细分

    1. 在当前线程中启动线程T,然后继续执行当前线程中的其它任务,最后在当前线程中获取T的返回值
    2. 在当前线程中启动线程T,然后继续执行当前线程中的其它任务R1,等待T执行完成,当T执行完成后,继续执行当前线程中的其它任务R2,最后获取T的返回值
    3. 在当前线程中启动线程T,只要T在执行就执行任务R,最后获取T的返回值

    下面,我将一一给出例子:

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

    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

    1.2 在当前线程中启动线程T,然后继续执行当前线程中的其它任务R1,等待T执行完成,当T执行完成后,继续执行当前线程中的其它任务R2,最后获取T的返回值

    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

    1.3 在当前线程中启动线程T,只要T在执行就执行任务R,最后获取T的返回值

    [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

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

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

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

  • 相关阅读:
    HDU5000 (DP + 规律)
    HDU5127 神坑题---vector 、 list 、 deque 的用法区别
    HDU5128 细心、细心、细心
    dij单源最短路纯模板
    POJ 1236 SCC+缩点
    SCC(强连通分量)
    用树状数组求数组内的逆序对数
    HDU 1811 并查集
    大数模板,只要不是手敲,非常好用
    市赛
  • 原文地址:https://www.cnblogs.com/czy/p/1648139.html
Copyright © 2020-2023  润新知