• ABCD四个顺序执行方法,拓展性延申


    今天在群里,有人问
    有几个void返回值的方法,但是我想让这几个方法有执行顺序,要怎么处理,ABCD 四个方法,依次执行,但是这几个方法都是无返回值的

    这个问题其实很简单,如果方法是同步方法,直接四个方法连续写就好了,比如:

        static void Main()
        {
               A();
               B();
               C();
               D();
        }
    

    但是如果方法里面包含了耗时操作(数据提交或者文件操作等),那么四个这样写就有问题了,执行顺序就错掉了,我们需要利用callback函数来进行操作,但是本着能不动原方法就不动的理念,我们使用Task的OnCompleted事件(.net framework中可以使用BeginInvoke(callback,null))来做处理

    1. 如果方法有返回值,则使用Func,或者Func<>
    2. 如果方法没有返回值,则使用Action,或者Action<>

    1. 无返回值在.net core中使用Task的OnCompleted事件

    由于是没有返回值的方法,我们使用
    例如

         static void Main()
        {
               Action action1 = () => {
                    Thread.Sleep(1000);
                    Console.WriteLine("action1");
                };
    
                Action action2 = () => {
                    Thread.Sleep(2000);
                    Console.WriteLine("action2");
                };
    
                Action action3 = () => {
                    Thread.Sleep(3000);
                    Console.WriteLine("action3");
                };
    
                Action action4 = () => {
                    Thread.Sleep(3000);
                    Console.WriteLine("action4");
                };
                Stack st = new Stack();
                st.Push(action2);
                st.Push(action3);
                st.Push(action4);
    
                void MyAsynCallback()
                {
                    if (st.Count > 0)
                    {
                        var action = (Action)st.Pop();
                        Task.Run(action).GetAwaiter().OnCompleted(() =>
                        {
                            MyAsynCallback();
                        });
                    }
                }
                Task.Run(action1).GetAwaiter().OnCompleted(() =>
                {
                    MyAsynCallback();
                });
                Console.ReadLine();
                //Stack的Pop是先进后出,输出顺序action1 action4 action3 action2
        }
    

    我们可以将Stack改成其他的,比如List、Queue等,自行判断是否需要手动弹出action即可

    2. 无返回值在.net framework中使用BeginInvoke

         static void Main()
        {
               Action action1 = () => {
                    Thread.Sleep(1000);
                    Console.WriteLine("action1");
                };
    
                Action action2 = () => {
                    Thread.Sleep(2000);
                    Console.WriteLine("action2");
                };
    
                Action action3 = () => {
                    Thread.Sleep(3000);
                    Console.WriteLine("action3");
                };
    
                Action action4 = () => {
                    Thread.Sleep(3000);
                    Console.WriteLine("action4");
                };
                Stack st = new Stack();
                st.Push(action2);
                st.Push(action3);
                st.Push(action4);
    
                void MyAsynCallback(IAsyncResult async)
                {
                    if (st.Count > 0)
                    {
                        var action = (Action)st.Pop();
                        action.BeginInvoke(new AsyncCallback(MyAsynCallback),null);
                    }
                }
                action1.BeginInvoke(new AsyncCallback(MyAsynCallback), null);
                Console.ReadLine();
                //Stack的Pop是先进后出,输出顺序action1 action4 action3 action2
        }
    

    3. 有返回值在.net core中使用Task的OnCompleted事件

    由于是没有返回值的方法,我们使用
    例如

         static void Main()
        {
                Func<int> func1 = () => {
                    Thread.Sleep(1000);
                    Console.WriteLine("func1");
                    return 1;
                };
    
                Func<int> func2 = () => {
                    Thread.Sleep(2000);
                    Console.WriteLine("func2");
                    return 1;
                };
    
                Func<int> func3 = () => {
                    Thread.Sleep(3000);
                    Console.WriteLine("func3");
                    return 0;
                };
    
                Func<int> func4 = () => {
                    Thread.Sleep(3000);
                    Console.WriteLine("func4");
                    return 1;
                };
                Stack st = new Stack();
                st.Push(func2);
                st.Push(func3);
                st.Push(func4);
    
                void MyAsynCallback(int result)
                {
                    if (st.Count > 0 && result > 0)
                    {
                        var action = (Func<int>)st.Pop();
                        var task1 = Task.Run(action);
                        task1.GetAwaiter().OnCompleted(() =>
                        {
                            MyAsynCallback(task1.Result);
                        });
                    }
                }
                var task = Task.Run(func1);
    
                task.GetAwaiter().OnCompleted(() =>
                {
                    MyAsynCallback(task.Result);
                });
                Console.ReadLine();
                //Stack的Pop是先进后出,输出顺序func1 func4 func3 func2
        }
    

    4. 有返回值在.net framework中使用BeginInvoke

         delegate int dele_func(int a);
         static void Main()
         {
                Func<int> func1 = () => {
                    Thread.Sleep(1000);
                    Console.WriteLine("func1");
                    return 1;
                };
    
                Func<int> func2 = () => {
                    Thread.Sleep(2000);
                    Console.WriteLine("func2");
                    return 1;
                };
    
                Func<int> func3 = () => {
                    Thread.Sleep(3000);
                    Console.WriteLine("func3");
                    return 1;
                };
    
                Func<int> func4 = () => {
                    Thread.Sleep(3000);
                    Console.WriteLine("func4");
                    return 1;
                };
                Stack st = new Stack();
                st.Push(func2);
                st.Push(func3);
                st.Push(func4);
    
    
                void MyAsynCallback(IAsyncResult async)
                {
                    dele_func dele_Func2 = (dele_func)async.AsyncState;
                    int result = dele_Func2.EndInvoke(async);
                    if (st.Count > 0 && result > 0)
                    {
                        var action = (Func<int>)st.Pop();
                        dele_func dele_Func1 = new dele_func((int a) => { return action.Invoke(); });
                        IAsyncResult asyncResult1 = dele_Func1.BeginInvoke(0, new AsyncCallback(MyAsynCallback), dele_Func1);
                    }
                }
                dele_func dele_Func = new dele_func((int a) => { return func1.Invoke(); });
                IAsyncResult asyncResult = dele_Func.BeginInvoke(0, new AsyncCallback(MyAsynCallback), dele_Func);
                Console.ReadLine();
                //Stack的Pop是先进后出,输出顺序func1 func4 func3 func2
         }
    

    有返回值时,可以根据result的判断,来判断是否继续往下执行

    如有问题,欢迎指正

  • 相关阅读:
    海岛争霸
    hihocoder 1089 最短路径·二:Floyd算法
    hihocoder1081 :最短路径·一
    [蓝桥杯][历届试题]蚂蚁感冒
    牛客网Wannafly挑战赛27 A: 灰魔法师
    hdu1875:畅通工程再续
    hdu1863:畅通工程
    hdu1879:继续畅通工程
    hdu1233:还是畅通工程
    洛谷 P1546 最短网络 Agri-Net
  • 原文地址:https://www.cnblogs.com/wangpengzong/p/15892850.html
Copyright © 2020-2023  润新知