zoukankan      html  css  js  c++  java
  • C# 同步调用 异步调用 异步回调 多线程的作用

    同步调用   : 委托的Invoke方法用来进行同步调用。同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行。

    异步调用  :同步调用会阻塞线程,如果是要调用一项繁重的工作(如大量IO操作),可能会让程序停顿很长时间,造成糟糕
    的用户体验,这时候异步调用就很有必要了。
    异步调用不阻塞线程,而是把调用塞到线程池中,程序主线程或UI线程可以继续执行。
    委托的异步调用通过BeginInvoke和EndInvoke来实现。

    异步回调函数  :当异步调用时,主线程并没有等待,而是直接向下运行了。
    但是问题依然存在,当主线程运行到EndInvoke时,如果这时调用没有结束(这种情况很可能出现),这时为了等待调用结果,线程依旧会被阻塞。
    解决的办法是用回调函数,当调用结束时会自动调用回调函数

    同步调用程序实现

    class Program
          {
              //同步调用
              //委托的Invoke方法用来进行同步调用。同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行。
               public delegate int AddHandler(int a,int b);//声明委托
               static void Main(string[] args)
                    {
                         Console.WriteLine("*******(同步调用)SyncInvokeTest*******");
                         AddHandler handler = new AddHandler(Add);//定义委托,传入参数
                         int result = handler.Invoke(1, 2);//委托的同步调用,主线程执行到此时停止,即阻塞。调用同步调用委托的的方法,执行此方法。
                         Console.WriteLine("(继续做其他的事)Do other work.....");//other work 是指Add方法,进行两数相加操作。
                         Console.WriteLine(result);
                         Console.ReadLine();
                     }

                private static int Add(int a, int b)//一个加法方法是一个线程
                     {
                         Console.WriteLine("Computing"+a+" + "+b+"...");
                         Thread.Sleep(9000);//模拟方法进行9秒
                         Console.WriteLine("computing complete.");
                         return a + b;
                      }
          }

    异步调用程序实现

    class Program
            {
                 //**************异步调用***********
                //异步调用不阻塞线程,而是把调用塞到线程池中,程序主线程或UI线程可以继续执行。
                //委托的异步调用通过BeginInvoke和EndInvoke来实现。
                public delegate int AddHandler(int a,int b);
                static void Main(string[] args)
                      {
                           Console.WriteLine("********(异步调用)AsyncInvokeTest******");
                           AddHandler handler = new AddHandler(Add);
                           IAsyncResult result = handler.BeginInvoke(1, 2, null, null);
                           Console.WriteLine("(继续做其他的事)do other work...");
                           Console.WriteLine(handler.EndInvoke(result));
                           Console.ReadLine();
                       }

                  private static int Add(int a, int b)
                      {
                          Console.WriteLine("computing "+a+"+"+b+"....");
                          Thread.Sleep(9000);//模拟方法进行9秒
                          Console.WriteLine("computing complete");
                          return a + b;
                       }
          }

    异步调用加入回调函数程序实现

    class Program
           {
                 //**************异步回调***********
                 //用回调函数,当调用结束时会自动调用回调函数,解决了为等待调用结果,而让线程依旧被阻塞的局面。

                //注意: BeginInvoke和EndInvoke必须成对调用.即使不需要返回值,但EndInvoke还是必须调用,否则可能会造成内存泄漏。
                public delegate int AddHandler(int a, int b);
                static void Main(string[] args)
                        {
                             Console.WriteLine("********(异步回调调用)AsyncInvokeTest******");
                             AddHandler handler = new AddHandler(Add);
                             IAsyncResult result = handler.BeginInvoke(1, 2, new AsyncCallback(AddComplete),"AsycState:OK");
                             Console.WriteLine("(继续做其他的事)do other work...");
                             // Console.WriteLine(handler.EndInvoke(result));//对于每个异步操作只能调用一次EndInvoke()方法。
                             Console.ReadLine();
                         }

                  private static int Add(int a, int b)
                         {
                             Console.WriteLine("computing " + a + "+" + b + "....");
                             Thread.Sleep(3000);//模拟方法进行9秒
                              Console.WriteLine("computing complete");
                             return a + b;
                         }

                 static void AddComplete(IAsyncResult result)//异步回调函数
                        {
                            AddHandler handler = (AddHandler) ((AsyncResult) result).AsyncDelegate;
                           Console.WriteLine(handler.EndInvoke(result));
                           Console.WriteLine(result.AsyncState);
                         }
                 //异步委托,也可以参考如下写法:
                //Action<object> action=(obj)=>method(obj);
                //action.BeginInvoke(obj,ar=>action.EndInvoke(ar),null);
               //简简单单两句话就可以完成一部操作。
           }

    多线程是为了提高用户体验,解决窗体界面假死状态的好的选择。同步线程是阻塞线程,对提高用户体验和界面假死没什么帮助。异步线程才可以提高程序的性能,和用户体验。平时说的多线程是指异步线程。

  • 相关阅读:
    bzoj1218 本来dp 但是数据弱 枚举可过
    bzoj1816二分答案 扑克牌
    bzoj2748 水dp
    最长上升子序列(nlog n)
    bzoj1798线段树。。调的要死
    HTML5 移动开发 (HTML5标签和属性)
    关于全屏布局
    关于z-index这个层级的问题
    面板数据模型
    竞争模型
  • 原文地址:https://www.cnblogs.com/yanyao/p/5340670.html
Copyright © 2011-2022 走看看