zoukankan      html  css  js  c++  java
  • C#异步

    本文在于巩固基础

    我们先来看看同步的概念:同步指的是按顺序执行,也就是说只有这个方法执行完才能执行下一个方法

    异步:不同于同步中按顺序执行,当执行异步操作时,不等待方法或者操作完成,就执行下一个方法,等到空闲时间时再去处理异步调用的方法

    我们还是来看看几个demo,以便能够更加清晰的了解C#异步编程

     public class AsyncDemo
        {
            public void Method1()
            {
                Thread.Sleep(1000);
                Console.WriteLine("this is Method1");
            }
    
            public void Method2()
            {
                Console.WriteLine("this is Method2");
            }
        }
    class Program
        {
            public delegate void Del();
    
            public static Del demoDel;
            static void Main(string[] args)
            {
                var demo = new AsyncDemo();
                demoDel += demo.Method1;
                demoDel.BeginInvoke(null, null);
                demo.Method2();
                Console.ReadLine();
            }
        }

    Console.ReadLine();用于阻塞等待,不然main函数执行完程序就结束了,异步方法就不会执行

    这是一个很简单的异步调用实例

    其运行结果:

    this is Method2
    this is Method1

    BeginInvoke 方法用于启动C#异步调用。它与您需要异步执行的方法具有相同的参数,只不过还有两个额外的参数(将在稍后描述)。BeginInvoke 立即返回,不等待C#异步调用完成。BeginInvoke 返回 IasyncResult,可用于监视调用进度。

    所以先执行Method1的时候就不会直接返回结果,而是执行下一个方法,这样可以不用等待Method1执行完成,等到Method1方法执行完成后就可以输出Method1操作结果

    当然你可以在你想到的地方输出Method1的结果

    在AsyncDemo加入Method3

     public void Method3()
            {
                Console.WriteLine("this is Method3");
            }
    class Program
    {
    public delegate void Del(); public static Del demoDel; static void Main(string[] args) { var demo = new AsyncDemo(); demoDel += demo.Method1; demoDel.BeginInvoke(null, null); demo.Method2(); demo.Method3(); Console.ReadLine(); } }

    这样的输出结果是:

    this is Method2
    this is Method3
    this is Method1

    如果我想要在Method2方法执行完就去搜索Method1的结果,结束这个异步调用,就可以使用EndInvoke方法

    EndInvoke 方法用于检索C#异步调用结果。调用 BeginInvoke 后可随时调用 EndInvoke 方法;如果C#异步调用未完成,EndInvoke 将一直阻塞到C#异步调用完成。EndInvoke 的参数包括您需要异步执行的方法的 out 和 ref 参数(在 Visual Basic 中为 ByRef 和 ByRef)以及由 BeginInvoke 返回的 IAsyncResult。

     class Program
        {
            public delegate void Del();
    
            public static Del demoDel;
            static void Main(string[] args)
            {
                var demo = new AsyncDemo();
                demoDel += demo.Method1;
                IAsyncResult ir=demoDel.BeginInvoke(null, null);
                demo.Method2();
                demoDel.EndInvoke(ir);
                demo.Method3();
                Console.ReadLine();
            }
        }

    this is Method2
    this is Method1
    this is Method3

    调用了 BeginInvoke 后,可以:

    · 进行某些操作,然后调用 EndInvoke 一直阻塞到调用完成。

    · 使用 IAsyncResult.AsyncWaitHandle 获取 WaitHandle,使用它的 WaitOne 方法将执行一直阻塞到发出 WaitHandle 信号,然后调用 EndInvoke。

    · 轮询由 BeginInvoke 返回的 IAsyncResult,确定C#异步调用何时完成,然后调用 EndInvoke。

    · 将用于回调方法的委托传递给 BeginInvoke。该方法在C#异步调用完成后在 ThreadPool 线程上执行,它可以调用 EndInvoke。

    警告:始终在C#异步调用完成后调用 EndInvoke。

    还可以使用IAsyncResult提供的AsyncWaitHandler等待句柄对象,它定义了一序列的WaitOne重载方法。在WaitOne通过参数指定的时间段"等待句柄"对象的状态转为Signaled,此时WaitOne方法返回true;如果超出这个时间则返回false

    class Program
        {
            public delegate void Del();
    
            public static Del demoDel;
            static void Main(string[] args)
            {
                var demo = new AsyncDemo();
                demoDel += demo.Method1;
                IAsyncResult ir=demoDel.BeginInvoke(null, null);
                demo.Method2();
                while (!ir.AsyncWaitHandle.WaitOne(400))
                {
                    Console.WriteLine(".");
                }
                demoDel.EndInvoke(ir);
                demo.Method3();
                Console.ReadLine();
            }
        }

    运行结果

    this is Method2
    .
    .
    this is Method1
    this is Method3

     EndInvoke方法是通过轮询的方式来判断异步操作是否完成,这会在循环等待浪费不少时间,我们可以用异步回调,在方法执行完成后自动调用一个方法

    注意回调方法的返回值类型是void,只能有一个IAsyncResult类型的参数,并且要在方法体中调用EndInvoke来取回方法执行的结果,另外result参数的AsyncState属性包含了外界传入的参数信息

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace Async
    {
        public delegate void Del();
        public class AsyncDemo
        {
            public Del DemoDel;
            public void Method1()
            {
                Thread.Sleep(1000);
                Console.WriteLine("this is Method1");
            }
    
            public void Method2()
            {
                Console.WriteLine("this is Method2");
            }
    
            public void Method3()
            {
                Console.WriteLine("this is Method3");
            }
    
            public void MethodCompletedCallBack(IAsyncResult ir)
            {
                string str=(string) ir.AsyncState;
                Console.WriteLine(str);
                Console.WriteLine("this is callback");
                
            }
    
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Async;
    
    namespace BlogTest
    {
        public delegate void Del();
        class Program
        {
            
    
            
            static void Main(string[] args)
            {
                string str = "hello world";
                var demo = new AsyncDemo();
                demo.DemoDel += demo.Method1;
                IAsyncResult ir=demo.DemoDel.BeginInvoke(new AsyncCallback(demo.MethodCompletedCallBack), str);
                demo.Method2();
                demo.Method3();
                Console.ReadLine();
    
            }
        }
    }

    this is Method2
    this is Method3
    this is Method1
    hello world
    this is callback

  • 相关阅读:
    是否允许爬取
    爬虫知识随记
    利用requestespyqueryBeautifulSoup爬取某租房公寓(深圳市)4755条租房信息及总结
    PySpider框架学习
    利用selenium模拟谷歌抓取淘宝商品美食信息并存储到mongodb练习(附详细注释)
    获取豆瓣读书所有热门标签并保存到mongodb数据库
    selenium学习之元素等待(四)
    selenium学习之切换网页(三)
    jmeter在不同环境中脚本执行切换配置
    jmeter中jdbc参数化以及引用参数
  • 原文地址:https://www.cnblogs.com/jixinyu/p/4306646.html
Copyright © 2011-2022 走看看