您的位置:新葡亰496net > 奥门新萄京娱乐场 > 的那些事儿,Net异步实例讲解

的那些事儿,Net异步实例讲解

发布时间:2019-08-31 04:39编辑:奥门新萄京娱乐场浏览(111)

    提起异步,Thread,Task,async/await,IAsyncResult 必得调控

    C#中 Thread,Task,Async/Await,IAsyncResult 的那个事儿!,

    提起异步,Thread,Task,async/await,IAsyncResult 这一个东西自然是绕不开的,明日就来千家万户聊聊他们

    的那些事儿,Net异步实例讲解。提起异步,Thread,Task,async/await,IAsyncResult 那么些事物一定是绕不开的,前几天就来每家每户聊聊他们

    C#中 Thread,Task,Async/Await,IAsyncResult 的那么些事情!,

    谈起异步,Thread,Task,async/await,IAsyncResult 这个东西自然是绕不开的,今日就来千家万户聊聊他们

     

    1.线程(Thread)

     

    二十四线程的意思在于三个应用程序中,有四个实践部分能够同期施行;对于相比较耗费时间的操作(举例io,数据库操作),恐怕等待响应(如WCF通讯)的操作,能够单独开启后台线程来实行,那样主线程就不会卡住,能够承接往下进行;等到后台线程实行达成,再文告主线程,然后做出相应操作!

     

    在C#中开启新线程相比轻便

     

    static void Main(string[] args)
    {
        Console.WriteLine("主线程开始");
        //IsBackground=true,将其设置为后台线程
        Thread t = new Thread(Run) { IsBackground = true };
        t.Start();
       Console.WriteLine("主线程在做其他的事!");
        //主线程结束,后台线程会自动结束,不管有没有执行完成
        //Thread.Sleep(300);
        Thread.Sleep(1500);
        Console.WriteLine("主线程结束");
    }
    static void Run()
    {
        Thread.Sleep(700);
        Console.WriteLine("这是后台线程调用");
    }
    

     

    进行结果如下图

     

    新葡亰496net 1

     

    能够看到在起步后台线程之后,主线程继续往下实施了,并从未等到后台线程实施完现在。

     

    谈到异步,Thread,Task,async/await,IAsyncResult 这么些事物必定是绕不开的,后日就来所有人家聊聊他们

    1.线程(Thread)

    八线程的意思在于贰个应用程序中,有三个实践部分能够而且执行;对于比较耗时的操作(举例io,数据库操作),也许等待响应(如WCF通讯)的操作,能够单独开启后台线程来实践,那样主线程就不会卡住,能够继续往下进行;等到后台线程试行完成,再通报主线程,然后做出相应操作!

    在C#中开启新线程相比轻松

    新葡亰496net 2

    static void Main(string[] args)
    {
        Console.WriteLine("主线程开始");
        //IsBackground=true,将其设置为后台线程
        Thread t = new Thread(Run) { IsBackground = true };
        t.Start();
       Console.WriteLine("主线程在做其他的事!");
        //主线程结束,后台线程会自动结束,不管有没有执行完成
        //Thread.Sleep(300);
        Thread.Sleep(1500);
        Console.WriteLine("主线程结束");
    }
    static void Run()
    {
        Thread.Sleep(700);
        Console.WriteLine("这是后台线程调用");
    }
    

    新葡亰496net 3

     推行结果如下图,

    新葡亰496net 4

    能够看出在起步后台线程之后,主线程继续往下实行了,并从未等到后台线程推行完事后。

    1.线程(Thread)

    三十二线程的含义在于二个应用程序中,有多少个施行部分能够况且实行;对于比较耗费时间的操作(举例io,数据库操作),也许等待响应(如WCF通讯)的操作,能够独立开启后台线程来实践,这样主线程就不会阻塞,可以接二连三往下推行;等到后台线程试行实现,再通报主线程,然后做出相应操作!

    在C#中展开新线程相比较轻易

    static void Main(string[] args)
    {
        Console.WriteLine("主线程开始");
        //IsBackground=true,将其设置为后台线程
        Thread t = new Thread(Run) { IsBackground = true };
        t.Start();
       Console.WriteLine("主线程在做其他的事!");
        //主线程结束,后台线程会自动结束,不管有没有执行完成
        //Thread.Sleep(300);
        Thread.Sleep(1500);
        Console.WriteLine("主线程结束");
    }
    static void Run()
    {
        Thread.Sleep(700);
        Console.WriteLine("这是后台线程调用");
    }
    

     推行结果如下图,

    新葡亰496net 5

    可以看到在运营后台线程之后,主线程继续往下进行了,并未等到后台线程实行完今后。

    1.线程(Thread)

    多线程的意义在于三个应用程序中,有多少个实施部分能够而且奉行;对于比较耗费时间的操作(举个例子io,数据库操作),可能等待响应(如WCF通讯)的操作,能够独自开启后台线程来推行,那样主线程就不会堵塞,能够持续往下实践;等到后台线程试行达成,再通报主线程,然后做出相应操作!

    在C#中张开新线程比较简单

    static void Main(string[] args)
    {
        Console.WriteLine("主线程开始");
        //IsBackground=true,将其设置为后台线程
        Thread t = new Thread(Run) { IsBackground = true };
        t.Start();
       Console.WriteLine("主线程在做其他的事!");
        //主线程结束,后台线程会自动结束,不管有没有执行完成
        //Thread.Sleep(300);
        Thread.Sleep(1500);
        Console.WriteLine("主线程结束");
    }
    static void Run()
    {
        Thread.Sleep(700);
        Console.WriteLine("这是后台线程调用");
    }
    

     推行结果如下图,

    新葡亰496net 6

    能够看到在开发银行后台线程之后,主线程继续往下进行了,并不曾等到后台线程推行完之后。

    1.1 线程池

     

    试想一下,要是有雅量的职责急需管理,比如网址后台对于HTTP央求的拍卖,那是还是不是要对每三个伸手成立三个后台线程呢?鲜明不合适,这会占领大批量内部存储器,并且多次地创制的长河也会严重影响进程,那怎么办吧?

     

    新葡亰496net,线程池就是为着消除这一主题素材,把创立的线程存起来,产生叁个线程池(里面有五个线程),当要拍卖任务时,若线程池中有闲暇线程(前贰个职责施行到位后,线程不会被回收,会被装置为空闲状态),则从来调用线程池中的线程实行(例asp.net管理机制中的Application对象),使用事例:

     

    for (int i = 0; i < 10; i  )
    {
        ThreadPool.QueueUserWorkItem(m =>
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString());
        });
    }
    Console.Read();
    

     

    运营结果:

     

    新葡亰496net 7

     

    能够见见,纵然进行了10次,但并不曾创建拾贰个线程。

     

    1.2 信号量(Semaphore)

     

    塞马phore肩负协调线程,能够界定对某一财富访问的线程数量,这里对SemaphoreSlim类的用法做八个简单的事例:

     

    static SemaphoreSlim semLim = new SemaphoreSlim(3); //3表示最多只能有三个线程同时访问
    static void Main(string[] args)
    {
        for (int i = 0; i < 10; i  )
        {
            new Thread(SemaphoreTest).Start();
        }
        Console.Read();
    }
    static void SemaphoreTest()
    {
        semLim.Wait();
        Console.WriteLine("线程"   Thread.CurrentThread.ManagedThreadId.ToString()   "开始执行");
        Thread.Sleep(2000);
        Console.WriteLine("线程"   Thread.CurrentThread.ManagedThreadId.ToString()   "执行完毕");
        semLim.Release();
    }
    

     

    实行结果如下:

     

    新葡亰496net 8

     

    新葡亰496net 9

     

    能够看来,刚开始唯有五个线程在推行,当一个线程实行达成并释放之后,才会有新的线程来施行办法!

     

    除却SemaphoreSlim类,还可以运用Semaphore类,感到越来越灵敏,感兴趣的话能够搜一下,这里就不做示范了!

     

    1.线程(Thread)

    二十八线程的含义在于二个应用程序中,有八个试行部分可以同一时候试行;对于比较耗时的操作(举例io,数据库操作),只怕等待响应(如WCF通讯)的操作,能够独立开启后台线程来实行,那样主线程就不会阻塞,能够继续往下实行;等到后台线程试行完结,再布告主线程,然后做出相应操作!

    在C#中张开新线程相比轻松

    static void Main(string[] args)
    {
        Console.WriteLine("主线程开始");
        //IsBackground=true,将其设置为后台线程
        Thread t = new Thread(Run) { IsBackground = true };
        t.Start();
       Console.WriteLine("主线程在做其他的事!");
        //主线程结束,后台线程会自动结束,不管有没有执行完成
        //Thread.Sleep(300);
        Thread.Sleep(1500);
        Console.WriteLine("主线程结束");
    }
    static void Run()
    {
        Thread.Sleep(700);
        Console.WriteLine("这是后台线程调用");
    }
    

     试行结果如下图,

    新葡亰496net 10

    能够看看在运转后台线程之后,主线程继续往下进行了,并未等到后台线程实践完之后。

    1.1 线程池

    试想一下,假使有大气的职分急需管理,举例网址后台对于HTTP央浼的拍卖,那是或不是要对每二个伸手成立二个后台线程呢?明显不合适,那会据有大批量内部存款和储蓄器,并且多次地创制的长河也会严重影响速度,那如何做呢?线程池正是为了化解这一主题材料,把成立的线程存起来,产生贰个线程池(里面有几个线程),当要管理任务时,若线程池中有空暇线程(前贰个职务实施到位后,线程不会被回收,会棉被服装置为空闲状态),则直接调用线程池中的线程试行(例asp.net处理体制中的Application对象),

    行使事例:

    新葡亰496net 11

    for (int i = 0; i < 10; i  )
    {
        ThreadPool.QueueUserWorkItem(m =>
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString());
        });
    }
    Console.Read();
    

    新葡亰496net 12

    运行结果:

    新葡亰496net 13

    能够观望,纵然施行了十二遍,但并未开创11个线程。

    1.1 线程池

    试想一下,尽管有雅量的职分急需管理,譬如网址后台对于HTTP乞求的拍卖,那是还是不是要对每叁个呼吁创制五个后台线程呢?明显不合适,那会占有大量内部存储器,並且再三地开创的历程也会严重影响进度,那怎么办吧?线程池就是为着减轻这一难题,把创立的线程存起来,产生三个线程池(里面有多少个线程),当要拍卖职责时,若线程池中有空余线程(前八个职分推行到位后,线程不会被回收,会被安装为空闲状态),则平素调用线程池中的线程实施(例asp.net管理体制中的Application对象),

    采取事例:

    for (int i = 0; i < 10; i  )
    {
        ThreadPool.QueueUserWorkItem(m =>
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString());
        });
    }
    Console.Read();
    

    运维结果:

    新葡亰496net 14

    能够看出,即便试行了14次,但并未开创十三个线程。

    1.1 线程池

    试想一下,倘诺有多量的任务急需管理,举例网址后台对于HTTP央浼的拍卖,那是或不是要对每八个呼吁成立一个后台线程呢?显著不合适,那会据有大量内存,并且一再地开创的长河也会严重影响进程,那如何做呢?线程池正是为着缓和这一主题素材,把制造的线程存起来,产生一个线程池(里面有七个线程),当要拍卖职分时,若线程池中有闲暇线程(前三个任务实行到位后,线程不会被回收,会被安装为空闲状态),则一向调用线程池中的线程试行(例asp.net管理体制中的Application对象),

    应用事例:

    for (int i = 0; i < 10; i  )
    {
        ThreadPool.QueueUserWorkItem(m =>
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString());
        });
    }
    Console.Read();
    

    运作结果:

    新葡亰496net 15

    能够看来,就算试行了14次,但并未开创11个线程。

    2.Task

     

    Task是.NET4.0加盟的,跟线程池ThreadPool的效能类似,用Task开启新职务时,会从线程池中调用线程,而Thread每趟实例化都会创设三个新的线程。

     

    Console.WriteLine("主线程启动");
    //Task.Run启动一个线程
    //Task启动的是后台线程,要在主线程中等待后台线程执行完毕,可以调用Wait方法
    //Task task = Task.Factory.StartNew(() => { Thread.Sleep(1500); Console.WriteLine("task启动"); });
    Task task = Task.Run(() => { 
        Thread.Sleep(1500);
        Console.WriteLine("task启动");
    });
    Thread.Sleep(300);
    task.Wait();
    Console.WriteLine("主线程结束");
    

     

    施行结果如下:

     

    新葡亰496net 16

     

    翻开新任务的不二等秘书技:Task.Run()恐怕Task.Factory.StartNew(),开启的是后台线程要在主线程中等待后台线程实行达成,能够行使Wait方法(会以协同的方法来执行)。不用Wait则会以异步的法子来推行。

     

    正如一下Task和Thread:

     

    static void Main(string[] args)
    {
        for (int i = 0; i < 5; i  )
        {
            new Thread(Run1).Start();
        }
        for (int i = 0; i < 5; i  )
        {
            Task.Run(() => { Run2(); });
        }
    }
    static void Run1()
    {
        Console.WriteLine("Thread Id ="   Thread.CurrentThread.ManagedThreadId);
    }
    static void Run2()
    {
        Console.WriteLine("Task调用的Thread Id ="   Thread.CurrentThread.ManagedThreadId);
    }
    

     

    施行结果:

     

    新葡亰496net 17

     

    能够看出来,直接用Thread会开启5个线程,用Task(用了线程池)开启了3个!

     

    1.1 线程池

    试想一下,假诺有大量的天职要求管理,比如网址后台对于HTTP央浼的管理,那是还是不是要对每二个诉求创立一个后台线程呢?分明不合适,那会占领多量内部存款和储蓄器,並且数十二回地创设的长河也会严重影响速度,那如何做吧?线程池就是为了化解这一标题,把创制的线程存起来,变成贰个线程池(里面有几个线程),当要拍卖职责时,若线程池中有空闲线程(前二个任务推行到位后,线程不会被回收,会被设置为空闲状态),则直接调用线程池中的线程施行(例asp.net管理机制中的Application对象),

    使用事例:

    for (int i = 0; i < 10; i  )
    {
        ThreadPool.QueueUserWorkItem(m =>
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString());
        });
    }
    Console.Read();
    

    运行结果:

    新葡亰496net 18

    能够看到,固然实施了十四回,但并不曾成立11个线程。

     1.2 信号量(Semaphore)

     Semaphore负担和煦线程,能够界定对某一能源访问的线程数量

     这里对SemaphoreSlim类的用法做一个简练的例证:

    新葡亰496net 19

    static SemaphoreSlim semLim = new SemaphoreSlim(3); //3表示最多只能有三个线程同时访问
    static void Main(string[] args)
    {
        for (int i = 0; i < 10; i  )
        {
            new Thread(SemaphoreTest).Start();
        }
        Console.Read();
    }
    static void SemaphoreTest()
    {
        semLim.Wait();
        Console.WriteLine("线程"   Thread.CurrentThread.ManagedThreadId.ToString()   "开始执行");
        Thread.Sleep(2000);
        Console.WriteLine("线程"   Thread.CurrentThread.ManagedThreadId.ToString()   "执行完毕");
        semLim.Release();
    }
    

    新葡亰496net 20

    的那些事儿,Net异步实例讲解。试行结果如下:

    新葡亰496net 21新葡亰496net 22

    能够看出,刚初阶只有多少个线程在施行,当三个线程试行实现并释放之后,才会有新的线程来施行措施!

    除去SemaphoreSlim类,还能使用Semaphore类,以为越来越灵活,感兴趣的话可以搜一下,这里就不做示范了!

     1.2 信号量(Semaphore)

     Semaphore肩负谐和线程,可以界定对某一能源访问的线程数量

     这里对SemaphoreSlim类的用法做二个轻松易行的例证:

    static SemaphoreSlim semLim = new SemaphoreSlim(3); //3表示最多只能有三个线程同时访问
    static void Main(string[] args)
    {
        for (int i = 0; i < 10; i  )
        {
            new Thread(SemaphoreTest).Start();
        }
        Console.Read();
    }
    static void SemaphoreTest()
    {
        semLim.Wait();
        Console.WriteLine("线程"   Thread.CurrentThread.ManagedThreadId.ToString()   "开始执行");
        Thread.Sleep(2000);
        Console.WriteLine("线程"   Thread.CurrentThread.ManagedThreadId.ToString()   "执行完毕");
        semLim.Release();
    }
    

    实施结果如下:

    新葡亰496net 23新葡亰496net 24

    能够看出,刚开始只有多个线程在实行,当二个线程推行完毕并释放之后,才会有新的线程来推行措施!

    除去塞马phoreSlim类,还是能够运用Semaphore类,感到更加灵敏,感兴趣的话能够搜一下,这里就不做示范了!

     1.2 信号量(Semaphore)

     Semaphore担当协和线程,能够限制对某一能源访谈的线程数量

     这里对SemaphoreSlim类的用法做三个轻便易行的例子:

    static SemaphoreSlim semLim = new SemaphoreSlim(3); //3表示最多只能有三个线程同时访问
    static void Main(string[] args)
    {
        for (int i = 0; i < 10; i  )
        {
            new Thread(SemaphoreTest).Start();
        }
        Console.Read();
    }
    static void SemaphoreTest()
    {
        semLim.Wait();
        Console.WriteLine("线程"   Thread.CurrentThread.ManagedThreadId.ToString()   "开始执行");
        Thread.Sleep(2000);
        Console.WriteLine("线程"   Thread.CurrentThread.ManagedThreadId.ToString()   "执行完毕");
        semLim.Release();
    }
    

    施行结果如下:

    新葡亰496net 25新葡亰496net 26

    能够见到,刚初阶独有多个线程在试行,当四个线程推行完结并释放之后,才会有新的线程来实施办法!

    除了SemaphoreSlim类,还足以应用Semaphore类,感觉越来越灵敏,感兴趣的话能够搜一下,这里就不做示范了!

    2.1 Task<TResult>

     

    Task<TResult>正是有再次回到值的Task,TResult就是回去值类型。

     

    Console.WriteLine("主线程开始");
    //返回值类型为string
    Task<string> task = Task<string>.Run(() => {
        Thread.Sleep(2000); 
        return Thread.CurrentThread.ManagedThreadId.ToString(); 
    });
    //会等到task执行完毕才会输出;
    Console.WriteLine(task.Result);
    Console.WriteLine("主线程结束");
    

     

    运作结果:

     

    新葡亰496net 27

     

    由此task.Result可以取到重回值,若取值的时候,后台线程还没实行完,则会等待其进行达成!

     

    差相当的少提一下:

     

    Task义务能够透过CancellationTokenSource类来撤除,认为用得非常少,用法比较简单,感兴趣的话能够搜一下!

     

     1.2 信号量(Semaphore)

     Semaphore肩负和煦线程,能够界定对某一财富访谈的线程数量

     这里对SemaphoreSlim类的用法做一个总结的例证:

    static SemaphoreSlim semLim = new SemaphoreSlim(3); //3表示最多只能有三个线程同时访问
    static void Main(string[] args)
    {
        for (int i = 0; i < 10; i  )
        {
            new Thread(SemaphoreTest).Start();
        }
        Console.Read();
    }
    static void SemaphoreTest()
    {
        semLim.Wait();
        Console.WriteLine("线程"   Thread.CurrentThread.ManagedThreadId.ToString()   "开始执行");
        Thread.Sleep(2000);
        Console.WriteLine("线程"   Thread.CurrentThread.ManagedThreadId.ToString()   "执行完毕");
        semLim.Release();
    }
    

    举办结果如下:

    新葡亰496net 28新葡亰496net 29

    可以看到,刚开始独有八个线程在实践,当叁个线程执行完毕并释放之后,才会有新的线程来推行措施!

    除开SemaphoreSlim类,还足以动用Semaphore类,感到更是灵活,感兴趣的话能够搜一下,这里就不做示范了!

    2.Task

    Task是.NET4.0投入的,跟线程池ThreadPool的效果与利益看似,用Task开启新任务时,会从线程池中调用线程,而Thread每便实例化都会创建二个新的线程。

    新葡亰496net 30

    Console.WriteLine("主线程启动");
    //Task.Run启动一个线程
    //Task启动的是后台线程,要在主线程中等待后台线程执行完毕,可以调用Wait方法
    //Task task = Task.Factory.StartNew(() => { Thread.Sleep(1500); Console.WriteLine("task启动"); });
    Task task = Task.Run(() => { 
        Thread.Sleep(1500);
        Console.WriteLine("task启动");
    });
    Thread.Sleep(300);
    task.Wait();
    Console.WriteLine("主线程结束");
    

    新葡亰496net 31

    实行结果如下:

    新葡亰496net 32

    敞开新职务的措施:Task.Run()可能Task.Factory.StartNew(),开启的是后台线程

    要在主线程中等待后台线程施行落成,能够使用Wait方法(会以协同的办法来推行)。不用Wait则会以异步的点子来实行。

    正如一下Task和Thread:

    新葡亰496net 33

    static void Main(string[] args)
    {
        for (int i = 0; i < 5; i  )
        {
            new Thread(Run1).Start();
        }
        for (int i = 0; i < 5; i  )
        {
            Task.Run(() => { Run2(); });
        }
    }
    static void Run1()
    {
        Console.WriteLine("Thread Id ="   Thread.CurrentThread.ManagedThreadId);
    }
    static void Run2()
    {
        Console.WriteLine("Task调用的Thread Id ="   Thread.CurrentThread.ManagedThreadId);
    }
    

    新葡亰496net 34

    施行结果:

    新葡亰496net 35

    能够看出来,间接用Thread会开启5个线程,用Task(用了线程池)开启了3个!

    2.Task

    Task是.NET4.0参加的,跟线程池ThreadPool的功力看似,用Task开启新职务时,会从线程池中调用线程,而Thread每一趟实例化都会创建一个新的线程。

    Console.WriteLine("主线程启动");
    //Task.Run启动一个线程
    //Task启动的是后台线程,要在主线程中等待后台线程执行完毕,可以调用Wait方法
    //Task task = Task.Factory.StartNew(() => { Thread.Sleep(1500); Console.WriteLine("task启动"); });
    Task task = Task.Run(() => { 
        Thread.Sleep(1500);
        Console.WriteLine("task启动");
    });
    Thread.Sleep(300);
    task.Wait();
    Console.WriteLine("主线程结束");
    

    实行结果如下:

    新葡亰496net 36

    翻开新职分的法子:Task.Run()可能Task.Factory.StartNew(),开启的是后台线程

    要在主线程中等待后台线程试行实现,能够接纳Wait方法(会以共同的措施来实施)。不用Wait则会以异步的艺术来举办。

    正如一下Task和Thread:

    static void Main(string[] args)
    {
        for (int i = 0; i < 5; i  )
        {
            new Thread(Run1).Start();
        }
        for (int i = 0; i < 5; i  )
        {
            Task.Run(() => { Run2(); });
        }
    }
    static void Run1()
    {
        Console.WriteLine("Thread Id ="   Thread.CurrentThread.ManagedThreadId);
    }
    static void Run2()
    {
        Console.WriteLine("Task调用的Thread Id ="   Thread.CurrentThread.ManagedThreadId);
    }
    

    实践结果:

    新葡亰496net 37

    能够看出来,直接用Thread会开启5个线程,用Task(用了线程池)开启了3个!

    2.Task

    Task是.NET4.0步入的,跟线程池ThreadPool的作用类似,用Task开启新职分时,会从线程池中调用线程,而Thread每回实例化都会创建三个新的线程。

    Console.WriteLine("主线程启动");
    //Task.Run启动一个线程
    //Task启动的是后台线程,要在主线程中等待后台线程执行完毕,可以调用Wait方法
    //Task task = Task.Factory.StartNew(() => { Thread.Sleep(1500); Console.WriteLine("task启动"); });
    Task task = Task.Run(() => { 
        Thread.Sleep(1500);
        Console.WriteLine("task启动");
    });
    Thread.Sleep(300);
    task.Wait();
    Console.WriteLine("主线程结束");
    

    进行结果如下:

    新葡亰496net 38

    开启新任务的议程:Task.Run()只怕Task.Factory.StartNew(),开启的是后台线程

    要在主线程中等待后台线程实施达成,能够动用Wait方法(会以联合的法子来实践)。不用Wait则会以异步的办法来实行。

    相比一下Task和Thread:

    static void Main(string[] args)
    {
        for (int i = 0; i < 5; i  )
        {
            new Thread(Run1).Start();
        }
        for (int i = 0; i < 5; i  )
        {
            Task.Run(() => { Run2(); });
        }
    }
    static void Run1()
    {
        Console.WriteLine("Thread Id ="   Thread.CurrentThread.ManagedThreadId);
    }
    static void Run2()
    {
        Console.WriteLine("Task调用的Thread Id ="   Thread.CurrentThread.ManagedThreadId);
    }
    

    实行结果:

    新葡亰496net 39

    可以看出来,直接用Thread会开启5个线程,用Task(用了线程池)开启了3个!

    3. async/await

     

    async/await是C#5.0中推出的,先上用法:

     

    static void Main(string[] args)
    {
        Console.WriteLine("-------主线程启动-------");
        Task<int> task = GetStrLengthAsync();
        Console.WriteLine("主线程继续执行");
        Console.WriteLine("Task返回的值"   task.Result);
        Console.WriteLine("-------主线程结束-------");
    }
    static async Task<int> GetStrLengthAsync()
    {
        Console.WriteLine("GetStrLengthAsync方法开始执行");
        //此处返回的<string>中的字符串类型,而不是Task<string>
        string str = await GetString();
        Console.WriteLine("GetStrLengthAsync方法执行结束");
        return str.Length;
    }
    static Task<string> GetString()
    {
       //Console.WriteLine("GetString方法开始执行")
        return Task<string>.Run(() =>
        {
            Thread.Sleep(2000);
            return "GetString的返回值";
        });
    }
    

     

    async用来修饰方法,评释那一个艺术是异步的,注解的章程的回来类型必需为:void,Task或Task<TResult>。

     

    await必得用来修饰Task或Task<TResult>,何况不得不现身在曾经用async关键字修饰的异步方法中。平时情状下,async/await成对出现才有含义,看看运维结果:

     

    新葡亰496net 40

     

    能够看出来,main函数调用GetStrLengthAsync方法后,在await在此以前,都以一块施行的,直到境遇await关键字,main函数才回来继续奉行。

     

    那么是还是不是是在遇到await关键字的时候程序自动开启了一个后台线程去试行GetString方法吧?

     

    后天把GetString方法中的这行注释加上,运维的结果是:

     

    新葡亰496net 41

     

    我们能够看出,在境遇await关键字后,未有继续试行GetStrLengthAsync方法后边的操作,也尚未马上反回到main函数中,而是进行了GetString的第一行,以此能够看清await这里并未拉开新的线程去实践GetString方法,而是以共同的措施让GetString方法实行,等到试行到GetString方法中的Task<string>.Run()的时候才由Task开启了后台线程!

     

    那正是说await的功力是什么啊?

     

    能够从字面上明白,上边提到task.wait能够让主线程等待后台线程实施完毕,await和wait类似,同样是等待,等待Task<string>.Run()初阶的后台线程施行实现,区别的是await不会堵塞主线程,只会让GetStrLengthAsync方法暂停实践。

     

    那便是说await是怎么达成的吗?有未有展开新线程去等待?

     

    新葡亰496net 42

     

    唯有四个线程(主线程和Task开启的线程)!至于怎么产生的(我也不知道......>_<),大家有意思味的话研商下啊!

     

    2.Task

    Task是.NET4.0参加的,跟线程池ThreadPool的功能相近,用Task开启新职务时,会从线程池中调用线程,而Thread每一次实例化都会创立贰个新的线程。

    Console.WriteLine("主线程启动");
    //Task.Run启动一个线程
    //Task启动的是后台线程,要在主线程中等待后台线程执行完毕,可以调用Wait方法
    //Task task = Task.Factory.StartNew(() => { Thread.Sleep(1500); Console.WriteLine("task启动"); });
    Task task = Task.Run(() => { 
        Thread.Sleep(1500);
        Console.WriteLine("task启动");
    });
    Thread.Sleep(300);
    task.Wait();
    Console.WriteLine("主线程结束");
    

    实行结果如下:

    新葡亰496net 43

    开启新职分的法子:Task.Run()大概Task.Factory.StartNew(),开启的是后台线程

    要在主线程中等待后台线程试行达成,能够运用Wait方法(会以协同的措施来进行)。不用Wait则会以异步的艺术来施行。

    相比一下Task和Thread:

    static void Main(string[] args)
    {
        for (int i = 0; i < 5; i  )
        {
            new Thread(Run1).Start();
        }
        for (int i = 0; i < 5; i  )
        {
            Task.Run(() => { Run2(); });
        }
    }
    static void Run1()
    {
        Console.WriteLine("Thread Id ="   Thread.CurrentThread.ManagedThreadId);
    }
    static void Run2()
    {
        Console.WriteLine("Task调用的Thread Id ="   Thread.CurrentThread.ManagedThreadId);
    }
    

    进行结果:

    新葡亰496net 44

    能够看出来,直接用Thread会开启5个线程,用Task(用了线程池)开启了3个!

    2.1 Task<TResult>

    Task<TResult>就是有重返值的Task,TResult就是回去值类型。

    新葡亰496net 45

    Console.WriteLine("主线程开始");
    //返回值类型为string
    Task<string> task = Task<string>.Run(() => {
        Thread.Sleep(2000); 
        return Thread.CurrentThread.ManagedThreadId.ToString(); 
    });
    //会等到task执行完毕才会输出;
    Console.WriteLine(task.Result);
    Console.WriteLine("主线程结束");
    

    新葡亰496net 46

    运营结果:

    新葡亰496net 47

    透过task.Result可以取到再次回到值,若取值的时候,后台线程还没实行完,则会等待其执行完结!

    简轻便单提一下:

    Task义务能够经过CancellationTokenSource类来裁撤,以为用得非常的少,用法相比简单,感兴趣的话能够搜一下!

    2.1 Task<TResult>

    Task<TResult>正是有再次来到值的Task,TResult便是回到值类型。

    Console.WriteLine("主线程开始");
    //返回值类型为string
    Task<string> task = Task<string>.Run(() => {
        Thread.Sleep(2000); 
        return Thread.CurrentThread.ManagedThreadId.ToString(); 
    });
    //会等到task执行完毕才会输出;
    Console.WriteLine(task.Result);
    Console.WriteLine("主线程结束");
    

    运作结果:

    新葡亰496net 48

    由此task.Result能够取到再次来到值,若取值的时候,后台线程还没实施完,则会等待其实行完成!

    粗略提一下:

    Task职务能够透过CancellationTokenSource类来撤废,认为用得相当少,用法比较轻易,感兴趣的话可以搜一下!

    2.1 Task<TResult>

    Task<TResult>正是有重返值的Task,TResult正是回到值类型。

    Console.WriteLine("主线程开始");
    //返回值类型为string
    Task<string> task = Task<string>.Run(() => {
        Thread.Sleep(2000); 
        return Thread.CurrentThread.ManagedThreadId.ToString(); 
    });
    //会等到task执行完毕才会输出;
    Console.WriteLine(task.Result);
    Console.WriteLine("主线程结束");
    

    运行结果:

    新葡亰496net 49

    因而task.Result能够取到再次来到值,若取值的时候,后台线程还没推行完,则会等待其施行完结!

    简言之提一下:

    Task职责能够透过CancellationTokenSource类来打消,以为用得相当少,用法比较轻便,感兴趣的话能够搜一下!

    4.IAsyncResult

     

    IAsyncResult自.NET1.1起就有了,包涵可异步操作的主意的类须求完结它,Task类就兑现了该接口

     

     

    新葡亰496net 50

     

    在不借助于Task的处境下怎么落实异步呢?

     

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("主程序开始--------------------");
            int threadId;
            AsyncDemo ad = new AsyncDemo();
            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);
     
            IAsyncResult result = caller.BeginInvoke(3000,out threadId, null, null);
            Thread.Sleep(0);
            Console.WriteLine("主线程线程 {0} 正在运行.",Thread.CurrentThread.ManagedThreadId)
            //会阻塞线程,直到后台线程执行完毕之后,才会往下执行
            result.AsyncWaitHandle.WaitOne();
            Console.WriteLine("主程序在做一些事情!!!");
            //获取异步执行的结果
            string returnValue = caller.EndInvoke(out threadId, result);
            //释放资源
            result.AsyncWaitHandle.Close();
            Console.WriteLine("主程序结束--------------------");
            Console.Read();
        }
    }
    public class AsyncDemo
    {
        //供后台线程执行的方法
        public string TestMethod(int callDuration, out int threadId)
        {
            Console.WriteLine("测试方法开始执行.");
            Thread.Sleep(callDuration);
            threadId = Thread.CurrentThread.ManagedThreadId;
            return String.Format("测试方法执行的时间 {0}.", callDuration.ToString());
        }
    }
    public delegate string AsyncMethodCaller(int callDuration, out int threadId);
    

     

    关键步骤就是壬申革命字体的局地,运行结果:

     

    新葡亰496net 51

     

    和Task的用法差距不是非常大!result.AsyncWaitHandle.WaitOne()就类似Task的Wait。

     

    5.Parallel

     

    最后说一下在循环中开启二十八线程的简短方法:

     

    Stopwatch watch1 = new Stopwatch();
    watch1.Start();
    for (int i = 1; i <= 10; i  )
    {
        Console.Write(i   ",");
        Thread.Sleep(1000);
    }
    watch1.Stop();
    Console.WriteLine(watch1.Elapsed);
    Stopwatch watch2 = new Stopwatch();
    watch2.Start();
    //会调用线程池中的线程
    Parallel.For(1, 11, i =>
    {
        Console.WriteLine(i   ",线程ID:"   Thread.CurrentThread.ManagedThreadId);
        Thread.Sleep(1000);
    });
    watch2.Stop();
    Console.WriteLine(watch2.Elapsed);
    

     

    运作结果:

     

    新葡亰496net 52

     

    循环List<T>:

     

    List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 6, 7, 8, 9 };
    Parallel.ForEach<int>(list, n =>
    {
        Console.WriteLine(n);
        Thread.Sleep(1000);
    });
    

     

    执行Action[]数组里面包车型大巴方法:

     

    Action[] actions = new Action[] { 
       new Action(()=>{
           Console.WriteLine("方法1");
       }),
        new Action(()=>{
           Console.WriteLine("方法2");
       })
    };
    Parallel.Invoke(actions);
    

    2.1 Task<TResult>

    Task<TResult>正是有再次来到值的Task,TResult正是回来值类型。

    Console.WriteLine("主线程开始");
    //返回值类型为string
    Task<string> task = Task<string>.Run(() => {
        Thread.Sleep(2000); 
        return Thread.CurrentThread.ManagedThreadId.ToString(); 
    });
    //会等到task执行完毕才会输出;
    Console.WriteLine(task.Result);
    Console.WriteLine("主线程结束");
    

    运行结果:

    新葡亰496net 53

    经过task.Result可以取到重临值,若取值的时候,后台线程还没施行完,则会等待其实施完结!

    轻易易行提一下:

    Task任务能够通过CancellationTokenSource类来撤废,感到用得十分少,用法相比较轻易,感兴趣的话能够搜一下!

     3. async/await

    async/await是C#5.0中生产的,先上用法:

    新葡亰496net 54

    static void Main(string[] args)
    {
        Console.WriteLine("-------主线程启动-------");
        Task<int> task = GetStrLengthAsync();
        Console.WriteLine("主线程继续执行");
        Console.WriteLine("Task返回的值"   task.Result);
        Console.WriteLine("-------主线程结束-------");
    }
    
    static async Task<int> GetStrLengthAsync()
    {
        Console.WriteLine("GetStrLengthAsync方法开始执行");
        //此处返回的<string>中的字符串类型,而不是Task<string>
        string str = await GetString();
        Console.WriteLine("GetStrLengthAsync方法执行结束");
        return str.Length;
    }
    
    static Task<string> GetString()
    {
       //Console.WriteLine("GetString方法开始执行")
        return Task<string>.Run(() =>
        {
            Thread.Sleep(2000);
            return "GetString的返回值";
        });
    }
    

    新葡亰496net 55

    async用来修饰方法,注解那几个主意是异步的,表明的法子的归来类型必需为:void,Task或Task<TResult>。

    await必需用来修饰Task或Task<TResult>,何况只可以出现在早已用async关键字修饰的异步方法中。经常意况下,async/await成对出现才有意义,

    会见运维结果:

    新葡亰496net 56

    能够看出来,main函数调用GetStrLengthAsync方法后,在await以前,都以一齐实践的,直到遇到await关键字,main函数才回去继续施行。

    那正是说是或不是是在遇见await关键字的时候程序自动开启了多个后台线程去试行GetString方法呢?

    近日把GetString方法中的那行注释加上,运转的结果是:

    新葡亰496net 57

    世家能够看看,在遇见await关键字后,未有继续试行GetStrLengthAsync方法前面包车型地铁操作,也平素不应声反回到main函数中,而是实行了GetString的率先行,以此能够看清await这里并从未开启新的线程去奉行GetString方法,而是以协同的主意让GetString方法推行,等到推行到GetString方法中的Task<string>.Run()的时候才由Task开启了后台线程!

    那就是说await的效能是怎么吗?

    能够从字面上精通,上面提到task.wait能够让主线程等待后台线程实践完成,await和wait类似,同样是伺机,等待Task<string>.Run()初始的后台线程施行达成,分歧的是await不会阻塞主线程,只会让GetStrLengthAsync方法暂停执行。

    那么await是怎么办到的呢?有未有打开新线程去等待?

    新葡亰496net 58

    唯有三个线程(主线程和Task开启的线程)!至于怎么完毕的(作者也不知道......>_<),大家有意思味的话钻探下吧!

     3. async/await

    async/await是C#5.0中出产的,先上用法:

    static void Main(string[] args)
    {
        Console.WriteLine("-------主线程启动-------");
        Task<int> task = GetStrLengthAsync();
        Console.WriteLine("主线程继续执行");
        Console.WriteLine("Task返回的值"   task.Result);
        Console.WriteLine("-------主线程结束-------");
    }
    
    static async Task<int> GetStrLengthAsync()
    {
        Console.WriteLine("GetStrLengthAsync方法开始执行");
        //此处返回的<string>中的字符串类型,而不是Task<string>
        string str = await GetString();
        Console.WriteLine("GetStrLengthAsync方法执行结束");
        return str.Length;
    }
    
    static Task<string> GetString()
    {
       //Console.WriteLine("GetString方法开始执行")
        return Task<string>.Run(() =>
        {
            Thread.Sleep(2000);
            return "GetString的返回值";
        });
    }
    

    async用来修饰方法,申明这些点子是异步的,注解的秘诀的回到类型必须为:void,Task或Task<TResult>。

    await必需用来修饰Task或Task<TResult>,并且不得不出现在曾经用async关键字修饰的异步方法中。日常情形下,async/await成对出现才有含义,

    拜会运转结果:

    新葡亰496net 59

    能够看出来,main函数调用GetStrLengthAsync方法后,在await以前,都以联合签名实践的,直到遭遇await关键字,main函数才回到继续实行。

    那么是还是不是是在遇见await关键字的时候程序自动开启了叁个后台线程去实践GetString方法呢?

    后天把GetString方法中的那行注释加上,运维的结果是:

    新葡亰496net 60

    我们能够看到,在蒙受await关键字后,未有继续实施GetStrLengthAsync方法后边的操作,也未有及时反回到main函数中,而是进行了GetString的率先行,以此能够剖断await这里并从未开启新的线程去试行GetString方法,而是以八只的措施让GetString方法实践,等到奉行到GetString方法中的Task<string>.Run()的时候才由Task开启了后台线程!

    那么await的职能是如何吗?

    能够从字面上通晓,上面提到task.wait能够让主线程等待后台线程试行完结,await和wait类似,一样是伺机,等待Task<string>.Run()初始的后台线程实施实现,区别的是await不会卡住主线程,只会让GetStrLengthAsync方法暂停实践。

    那么await是怎么产生的呢?有未有张开新线程去等待?

    新葡亰496net 61

    独有四个线程(主线程和Task开启的线程)!至于怎么做到的(小编也不知道......>_<),大家风乐趣的话切磋下呢!

     3. async/await

    async/await是C#5.0中推出的,先上用法:

    static void Main(string[] args)
    {
        Console.WriteLine("-------主线程启动-------");
        Task<int> task = GetStrLengthAsync();
        Console.WriteLine("主线程继续执行");
        Console.WriteLine("Task返回的值"   task.Result);
        Console.WriteLine("-------主线程结束-------");
    }
    
    static async Task<int> GetStrLengthAsync()
    {
        Console.WriteLine("GetStrLengthAsync方法开始执行");
        //此处返回的<string>中的字符串类型,而不是Task<string>
        string str = await GetString();
        Console.WriteLine("GetStrLengthAsync方法执行结束");
        return str.Length;
    }
    
    static Task<string> GetString()
    {
       //Console.WriteLine("GetString方法开始执行")
        return Task<string>.Run(() =>
        {
            Thread.Sleep(2000);
            return "GetString的返回值";
        });
    }
    

    async用来修饰方法,注脚这么些格局是异步的,表明的措施的归来类型必得为:void,Task或Task<TResult>。

    await必需用来修饰Task或Task<TResult>,而且不得不出现在已经用async关键字修饰的异步方法中。平日情状下,async/await成对现身才有含义,

    探望运转结果:

    新葡亰496net 62

    能够看出来,main函数调用GetStrLengthAsync方法后,在await之前,都以联合实施的,直到遭受await关键字,main函数才回到继续实践。

    那么是不是是在碰到await关键字的时候程序自动开启了多个后台线程去实行GetString方法吗?

    当今把GetString方法中的那行注释加上,运转的结果是:

    新葡亰496net 63

    我们能够见到,在碰到await关键字后,未有继续实施GetStrLengthAsync方法前面包车型地铁操作,也不曾马上反回到main函数中,而是进行了GetString的首先行,以此能够决断await这里并不曾拉开新的线程去推行GetString方法,而是以三只的不二诀要让GetString方法试行,等到实践到GetString方法中的Task<string>.Run()的时候才由Task开启了后台线程!

    那么await的遵守是怎么着呢?

    能够从字面上精通,下面提到task.wait能够让主线程等待后台线程实行完成,await和wait类似,同样是等待,等待Task<string>.Run()起先的后台线程试行实现,差别的是await不会堵塞主线程,只会让GetStrLengthAsync方法暂停实践。

    那么await是怎么达成的呢?有未有张开新线程去等待?

    新葡亰496net 64

    只有多个线程(主线程和Task开启的线程)!至于如何做到的(小编也不知道......>_<),大家风乐趣的话研商下啊!

     

     3. async/await

    async/await是C#5.0中生产的,先上用法:

    static void Main(string[] args)
    {
        Console.WriteLine("-------主线程启动-------");
        Task<int> task = GetStrLengthAsync();
        Console.WriteLine("主线程继续执行");
        Console.WriteLine("Task返回的值"   task.Result);
        Console.WriteLine("-------主线程结束-------");
    }
    
    static async Task<int> GetStrLengthAsync()
    {
        Console.WriteLine("GetStrLengthAsync方法开始执行");
        //此处返回的<string>中的字符串类型,而不是Task<string>
        string str = await GetString();
        Console.WriteLine("GetStrLengthAsync方法执行结束");
        return str.Length;
    }
    
    static Task<string> GetString()
    {
       //Console.WriteLine("GetString方法开始执行")
        return Task<string>.Run(() =>
        {
            Thread.Sleep(2000);
            return "GetString的返回值";
        });
    }
    

    async用来修饰方法,注脚这么些点子是异步的,证明的格局的归来类型必需为:void,Task或Task<TResult>。

    await必得用来修饰Task或Task<TResult>,并且不得不出现在已经用async关键字修饰的异步方法中。常常状态下,async/await成对出现才有含义,

    拜见运转结果:

    新葡亰496net 65

    能够看出来,main函数调用GetStrLengthAsync方法后,在await在此以前,都以一道执行的,直到遭受await关键字,main函数才回到继续推行。

    那么是还是不是是在蒙受await关键字的时候程序自动开启了贰个后台线程去实践GetString方法吧?

    今昔把GetString方法中的那行注释加上,运转的结果是:

    新葡亰496net 66

    大家能够见见,在碰到await关键字后,没有继续试行GetStrLengthAsync方法后边的操作,也尚未即时反回到main函数中,而是进行了GetString的第一行,以此能够看清await这里并未张开新的线程去实践GetString方法,而是以三头的方法让GetString方法实践,等到试行到GetString方法中的Task<string>.Run()的时候才由Task开启了后台线程!

    那么await的意义是什么样呢?

    能够从字面上精晓,下边提到task.wait能够让主线程等待后台线程奉行实现,await和wait类似,同样是等待,等待Task<string>.Run()开首的后台线程试行完结,不一样的是await不会堵塞主线程,只会让GetStrLengthAsync方法暂停实行。

    那正是说await是如何做到的呢?有未有展开新线程去等待?

    新葡亰496net 67

    独有四个线程(主线程和Task开启的线程)!至于怎么形成的(笔者也不知道......>_<),大家有意思味的话研商下吧!

    4.IAsyncResult

    IAsyncResult自.NET1.1起就有了,满含可异步操作的不二法门的类须要贯彻它,Task类就贯彻了该接口

    新葡亰496net 68

    在不依赖Task的气象下怎么落到实处异步呢?

    新葡亰496net 69

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("主程序开始--------------------");
            int threadId;
            AsyncDemo ad = new AsyncDemo();
            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);
    
            IAsyncResult result = caller.BeginInvoke(3000,out threadId, null, null);
            Thread.Sleep(0);
            Console.WriteLine("主线程线程 {0} 正在运行.",Thread.CurrentThread.ManagedThreadId)
            //会阻塞线程,直到后台线程执行完毕之后,才会往下执行
            result.AsyncWaitHandle.WaitOne();
            Console.WriteLine("主程序在做一些事情!!!");
            //获取异步执行的结果
            string returnValue = caller.EndInvoke(out threadId, result);
            //释放资源
            result.AsyncWaitHandle.Close();
            Console.WriteLine("主程序结束--------------------");
            Console.Read();
        }
    }
    public class AsyncDemo
    {
        //供后台线程执行的方法
        public string TestMethod(int callDuration, out int threadId)
        {
            Console.WriteLine("测试方法开始执行.");
            Thread.Sleep(callDuration);
            threadId = Thread.CurrentThread.ManagedThreadId;
            return String.Format("测试方法执行的时间 {0}.", callDuration.ToString());
        }
    }
    public delegate string AsyncMethodCaller(int callDuration, out int threadId);
    

    新葡亰496net 70

    关键步骤正是新民主主义革命字体的片段,运维结果:

    新葡亰496net 71

    和Task的用法差异不是非常大!result.AsyncWaitHandle.WaitOne()就疑似Task的Wait。

    4.IAsyncResult

    IAsyncResult自.NET1.1起就有了,富含可异步操作的法子的类须要完结它,Task类就达成了该接口

    新葡亰496net 72

    在不借助于Task的气象下怎么落到实处异步呢?

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("主程序开始--------------------");
            int threadId;
            AsyncDemo ad = new AsyncDemo();
            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);
    
            IAsyncResult result = caller.BeginInvoke(3000,out threadId, null, null);
            Thread.Sleep(0);
            Console.WriteLine("主线程线程 {0} 正在运行.",Thread.CurrentThread.ManagedThreadId)
            //会阻塞线程,直到后台线程执行完毕之后,才会往下执行
            result.AsyncWaitHandle.WaitOne();
            Console.WriteLine("主程序在做一些事情!!!");
            //获取异步执行的结果
            string returnValue = caller.EndInvoke(out threadId, result);
            //释放资源
            result.AsyncWaitHandle.Close();
            Console.WriteLine("主程序结束--------------------");
            Console.Read();
        }
    }
    public class AsyncDemo
    {
        //供后台线程执行的方法
        public string TestMethod(int callDuration, out int threadId)
        {
            Console.WriteLine("测试方法开始执行.");
            Thread.Sleep(callDuration);
            threadId = Thread.CurrentThread.ManagedThreadId;
            return String.Format("测试方法执行的时间 {0}.", callDuration.ToString());
        }
    }
    public delegate string AsyncMethodCaller(int callDuration, out int threadId);
    

    关键步骤正是乙丑革命字体的有的,运营结果:

    新葡亰496net 73

    和Task的用法差距不是异常的大!result.AsyncWaitHandle.WaitOne()就相近Task的Wait。

    4.IAsyncResult

    IAsyncResult自.NET1.1起就有了,饱含可异步操作的秘诀的类要求落成它,Task类就落到实处了该接口

    新葡亰496net 74

    在不重视Task的气象下怎么落到实处异步呢?

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("主程序开始--------------------");
            int threadId;
            AsyncDemo ad = new AsyncDemo();
            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);
    
            IAsyncResult result = caller.BeginInvoke(3000,out threadId, null, null);
            Thread.Sleep(0);
            Console.WriteLine("主线程线程 {0} 正在运行.",Thread.CurrentThread.ManagedThreadId)
            //会阻塞线程,直到后台线程执行完毕之后,才会往下执行
            result.AsyncWaitHandle.WaitOne();
            Console.WriteLine("主程序在做一些事情!!!");
            //获取异步执行的结果
            string returnValue = caller.EndInvoke(out threadId, result);
            //释放资源
            result.AsyncWaitHandle.Close();
            Console.WriteLine("主程序结束--------------------");
            Console.Read();
        }
    }
    public class AsyncDemo
    {
        //供后台线程执行的方法
        public string TestMethod(int callDuration, out int threadId)
        {
            Console.WriteLine("测试方法开始执行.");
            Thread.Sleep(callDuration);
            threadId = Thread.CurrentThread.ManagedThreadId;
            return String.Format("测试方法执行的时间 {0}.", callDuration.ToString());
        }
    }
    public delegate string AsyncMethodCaller(int callDuration, out int threadId);
    

    关键步骤就是革命字体的有个别,运转结果:

    新葡亰496net 75

    和Task的用法差距不是极大!result.AsyncWaitHandle.WaitOne()就类似Task的Wait。

    6.异步的回调

     

    为了简洁(偷懒),文中全体Task<TResult>的重临值都是间接用task.result获取,那样一旦后台职分未有试行实现的话,主线程会等待其试行完成。这样的话就和一块同样了,一般情状下不会这么用。轻松演示一下Task回调函数的使用:

     

    Console.WriteLine("主线程开始");
    Task<string> task = Task<string>.Run(() => {
        Thread.Sleep(2000); 
        return Thread.CurrentThread.ManagedThreadId.ToString(); 
    });
    //会等到任务执行完之后执行
    task.GetAwaiter().OnCompleted(() =>
    {
        Console.WriteLine(task.Result);
    });
    Console.WriteLine("主线程结束");
    Console.Read();
    

     

    施行结果:

     

    新葡亰496net 76

     

    OnCompleted中的代码会在职分试行到位今后实践!

     

    别的task.ContinueWith()也是三个最首要的点子:

     

    Console.WriteLine("主线程开始");
    Task<string> task = Task<string>.Run(() => {
        Thread.Sleep(2000); 
        return Thread.CurrentThread.ManagedThreadId.ToString(); 
    });
    task.GetAwaiter().OnCompleted(() =>
    {
        Console.WriteLine(task.Result);
    });
    task.ContinueWith(m=>{Console.WriteLine("第一个任务结束啦!我是第二个任务");});
    Console.WriteLine("主线程结束");
    Console.Read();
    

     

    施行结果:

     

    新葡亰496net 77

     

    孔蒂nueWith()方法能够让该后台线程继续施行新的天职。

     

    Task的应用依然比较灵敏的,大家能够斟酌下,好了,以上正是全体内容了,篇幅和力量都有数,希望对大家有用!

    Thread,Task,Async/Await,IAsyncResult 的那么些事情!, 提起异步,Thread,Task,async/await,IAsyncResult 那么些东西自然是绕不开的,后天就来依次...

    4.IAsyncResult

    IAsyncResult自.NET1.1起就有了,蕴涵可异步操作的办法的类必要完毕它,Task类就落实了该接口

    新葡亰496net 78

    在不依赖Task的情形下怎么落到实处异步呢?

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("主程序开始--------------------");
            int threadId;
            AsyncDemo ad = new AsyncDemo();
            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);
    
            IAsyncResult result = caller.BeginInvoke(3000,out threadId, null, null);
            Thread.Sleep(0);
            Console.WriteLine("主线程线程 {0} 正在运行.",Thread.CurrentThread.ManagedThreadId)
            //会阻塞线程,直到后台线程执行完毕之后,才会往下执行
            result.AsyncWaitHandle.WaitOne();
            Console.WriteLine("主程序在做一些事情!!!");
            //获取异步执行的结果
            string returnValue = caller.EndInvoke(out threadId, result);
            //释放资源
            result.AsyncWaitHandle.Close();
            Console.WriteLine("主程序结束--------------------");
            Console.Read();
        }
    }
    public class AsyncDemo
    {
        //供后台线程执行的方法
        public string TestMethod(int callDuration, out int threadId)
        {
            Console.WriteLine("测试方法开始执行.");
            Thread.Sleep(callDuration);
            threadId = Thread.CurrentThread.ManagedThreadId;
            return String.Format("测试方法执行的时间 {0}.", callDuration.ToString());
        }
    }
    public delegate string AsyncMethodCaller(int callDuration, out int threadId);
    

    关键步骤正是革命字体的一部分,运营结果:

    新葡亰496net 79

    和Task的用法差别不是极大!result.AsyncWaitHandle.WaitOne()就左近Task的Wait。

     5.Parallel

    最后说一下在循环中展开多线程的简要方法:

    新葡亰496net 80

    Stopwatch watch1 = new Stopwatch();
    watch1.Start();
    for (int i = 1; i <= 10; i  )
    {
        Console.Write(i   ",");
        Thread.Sleep(1000);
    }
    watch1.Stop();
    Console.WriteLine(watch1.Elapsed);
    
    Stopwatch watch2 = new Stopwatch();
    watch2.Start();
    
    //会调用线程池中的线程
    Parallel.For(1, 11, i =>
    {
        Console.WriteLine(i   ",线程ID:"   Thread.CurrentThread.ManagedThreadId);
        Thread.Sleep(1000);
    });
    watch2.Stop();
    Console.WriteLine(watch2.Elapsed);
    

    新葡亰496net 81

    运维结果:

    新葡亰496net 82

    循环List<T>:

    新葡亰496net 83

    List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 6, 7, 8, 9 };
    Parallel.ForEach<int>(list, n =>
    {
        Console.WriteLine(n);
        Thread.Sleep(1000);
    });
    

    新葡亰496net 84

    执行Action[]数组里面包车型大巴不二诀要:

    新葡亰496net 85

    Action[] actions = new Action[] { 
       new Action(()=>{
           Console.WriteLine("方法1");
       }),
        new Action(()=>{
           Console.WriteLine("方法2");
       })
    };
    Parallel.Invoke(actions);
    

    新葡亰496net 86

     5.Parallel

    最后说一下在循环中拉开八线程的简短方法:

    Stopwatch watch1 = new Stopwatch();
    watch1.Start();
    for (int i = 1; i <= 10; i  )
    {
        Console.Write(i   ",");
        Thread.Sleep(1000);
    }
    watch1.Stop();
    Console.WriteLine(watch1.Elapsed);
    
    Stopwatch watch2 = new Stopwatch();
    watch2.Start();
    
    //会调用线程池中的线程
    Parallel.For(1, 11, i =>
    {
        Console.WriteLine(i   ",线程ID:"   Thread.CurrentThread.ManagedThreadId);
        Thread.Sleep(1000);
    });
    watch2.Stop();
    Console.WriteLine(watch2.Elapsed);
    

    运维结果:

    新葡亰496net 87

    循环List<T>:

    List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 6, 7, 8, 9 };
    Parallel.ForEach<int>(list, n =>
    {
        Console.WriteLine(n);
        Thread.Sleep(1000);
    });
    

    执行Action[]数组里面包车型地铁主意:

    Action[] actions = new Action[] { 
       new Action(()=>{
           Console.WriteLine("方法1");
       }),
        new Action(()=>{
           Console.WriteLine("方法2");
       })
    };
    Parallel.Invoke(actions);
    

     5.Parallel

    最终说一下在循环中开启四线程的简练方法:

    Stopwatch watch1 = new Stopwatch();
    watch1.Start();
    for (int i = 1; i <= 10; i  )
    {
        Console.Write(i   ",");
        Thread.Sleep(1000);
    }
    watch1.Stop();
    Console.WriteLine(watch1.Elapsed);
    
    Stopwatch watch2 = new Stopwatch();
    watch2.Start();
    
    //会调用线程池中的线程
    Parallel.For(1, 11, i =>
    {
        Console.WriteLine(i   ",线程ID:"   Thread.CurrentThread.ManagedThreadId);
        Thread.Sleep(1000);
    });
    watch2.Stop();
    Console.WriteLine(watch2.Elapsed);
    

    运营结果:

    新葡亰496net 88

    循环List<T>:

    List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 6, 7, 8, 9 };
    Parallel.ForEach<int>(list, n =>
    {
        Console.WriteLine(n);
        Thread.Sleep(1000);
    });
    

    执行Action[]数组里面包车型客车方法:

    Action[] actions = new Action[] { 
       new Action(()=>{
           Console.WriteLine("方法1");
       }),
        new Action(()=>{
           Console.WriteLine("方法2");
       })
    };
    Parallel.Invoke(actions);
    

     5.Parallel

    最终说一下在循环中打开八线程的简要方法:

    Stopwatch watch1 = new Stopwatch();
    watch1.Start();
    for (int i = 1; i <= 10; i  )
    {
        Console.Write(i   ",");
        Thread.Sleep(1000);
    }
    watch1.Stop();
    Console.WriteLine(watch1.Elapsed);
    
    Stopwatch watch2 = new Stopwatch();
    watch2.Start();
    
    //会调用线程池中的线程
    Parallel.For(1, 11, i =>
    {
        Console.WriteLine(i   ",线程ID:"   Thread.CurrentThread.ManagedThreadId);
        Thread.Sleep(1000);
    });
    watch2.Stop();
    Console.WriteLine(watch2.Elapsed);
    

    运作结果:

    新葡亰496net 89

    循环List<T>:

    List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 6, 7, 8, 9 };
    Parallel.ForEach<int>(list, n =>
    {
        Console.WriteLine(n);
        Thread.Sleep(1000);
    });
    

    执行Action[]数组里面包车型客车措施:

    Action[] actions = new Action[] { 
       new Action(()=>{
           Console.WriteLine("方法1");
       }),
        new Action(()=>{
           Console.WriteLine("方法2");
       })
    };
    Parallel.Invoke(actions);
    

    6.异步的回调

    文中全数Task<TResult>的再次来到值都以一向用task.result获取,那样假使后台职分未有进行实现的话,主线程会等待其施行落成,那样的话就和一块同样了(看上去同样,但骨子里await的时候并不会变成线程的堵塞,web程序感到不到,不过wpf,winform那样的桌面程序若不采用异步,会招致UI线程的不通)。轻巧演示一下Task回调函数的利用:

    新葡亰496net 90

    Console.WriteLine("主线程开始");
    Task<string> task = Task<string>.Run(() => {
        Thread.Sleep(2000); 
        return Thread.CurrentThread.ManagedThreadId.ToString(); 
    });
    //会等到任务执行完之后执行
    task.GetAwaiter().OnCompleted(() =>
    {
        Console.WriteLine(task.Result);
    });
    Console.WriteLine("主线程结束");
    Console.Read();
    

    新葡亰496net 91

    推行结果:

    新葡亰496net 92

    OnCompleted中的代码会在任务实行到位之后试行!

    另外task.ContinueWith()也是贰个注重的不二法门:

    新葡亰496net 93

    Console.WriteLine("主线程开始");
    Task<string> task = Task<string>.Run(() => {
        Thread.Sleep(2000); 
        return Thread.CurrentThread.ManagedThreadId.ToString(); 
    });
    
    task.GetAwaiter().OnCompleted(() =>
    {
        Console.WriteLine(task.Result);
    });
    task.ContinueWith(m=>{Console.WriteLine("第一个任务结束啦!我是第二个任务");});
    Console.WriteLine("主线程结束");
    Console.Read();
    

    新葡亰496net 94

    推行结果:

    新葡亰496net 95

    ContinueWith()方法能够让该后台线程继续实施新的义务。

    6.异步的回调

    为了简洁(偷懒),文中全数Task<TResult>的再次回到值都以直接用task.result获取,这样一旦后台职务没有实行完毕的话,主线程会等待其实行达成。那样的话就和一道同样了,一般景况下不会这么用。轻巧演示一下Task回调函数的施用:

    Console.WriteLine("主线程开始");
    Task<string> task = Task<string>.Run(() => {
        Thread.Sleep(2000); 
        return Thread.CurrentThread.ManagedThreadId.ToString(); 
    });
    //会等到任务执行完之后执行
    task.GetAwaiter().OnCompleted(() =>
    {
        Console.WriteLine(task.Result);
    });
    Console.WriteLine("主线程结束");
    Console.Read();
    

    试行结果:

    新葡亰496net 96

    OnCompleted中的代码会在职责施行到位今后实行!

    其他task.ContinueWith()也是多少个根本的法子:

    Console.WriteLine("主线程开始");
    Task<string> task = Task<string>.Run(() => {
        Thread.Sleep(2000); 
        return Thread.CurrentThread.ManagedThreadId.ToString(); 
    });
    
    task.GetAwaiter().OnCompleted(() =>
    {
        Console.WriteLine(task.Result);
    });
    task.ContinueWith(m=>{Console.WriteLine("第一个任务结束啦!我是第二个任务");});
    Console.WriteLine("主线程结束");
    Console.Read();
    

    奉行结果:

    新葡亰496net 97

    孔蒂nueWith()方法能够让该后台线程继续试行新的天职。

    Task的运用依旧相比灵活的,咱们能够研商下,好了,以上就是全部内容了,篇幅和力量都有数,希望对大家有用!

     

    Thread,Task,Async/Await,IAsyncResult 的那个事情!, 谈到异步,Thread,Task,async/await,IAsyncResult 那几个东西自然是绕不开的,明日就来依次...

    6.异步的回调

    文中全部Task<TResult>的再次回到值都是直接用task.result获取,那样一旦后台职分未有实践完毕的话,主线程会等待其施行达成,那样的话就和共同同样了(看上去同样,但实则await的时候并不会促成线程的鸿沟,web程序感觉不到,不过wpf,winform那样的桌面程序若不采用异步,会导致UI线程的短路)。轻易演示一下Task回调函数的运用:

    Console.WriteLine("主线程开始");
    Task<string> task = Task<string>.Run(() => {
        Thread.Sleep(2000); 
        return Thread.CurrentThread.ManagedThreadId.ToString(); 
    });
    //会等到任务执行完之后执行
    task.GetAwaiter().OnCompleted(() =>
    {
        Console.WriteLine(task.Result);
    });
    Console.WriteLine("主线程结束");
    Console.Read();
    

    进行结果:

    新葡亰496net 98

    OnCompleted中的代码会在任务执行到位之后试行!

    别的task.ContinueWith()也是一个着重的形式:

    Console.WriteLine("主线程开始");
    Task<string> task = Task<string>.Run(() => {
        Thread.Sleep(2000); 
        return Thread.CurrentThread.ManagedThreadId.ToString(); 
    });
    
    task.GetAwaiter().OnCompleted(() =>
    {
        Console.WriteLine(task.Result);
    });
    task.ContinueWith(m=>{Console.WriteLine("第一个任务结束啦!我是第二个任务");});
    Console.WriteLine("主线程结束");
    Console.Read();
    

    实行结果:

    新葡亰496net 99

    ContinueWith()方法能够让该后台线程继续实行新的义务。

    Task的选用照旧相比较灵敏的,大家能够钻探下,好了,以上正是全体内容了,篇幅和力量都有数,希望对我们有用!

     

    6.异步的回调

    文中全部Task<TResult>的重临值都以直接用task.result获取,那样就算后台职责未有施行实现的话,主线程会等待其实践完成,这样的话就和联合一样了(看上去一样,但实质上await的时候并不会招致线程的隔离,web程序以为不到,可是wpf,winform那样的桌面程序若不采纳异步,会产生UI线程的堵截)。轻易演示一下Task回调函数的使用:

    Console.WriteLine("主线程开始");
    Task<string> task = Task<string>.Run(() => {
        Thread.Sleep(2000); 
        return Thread.CurrentThread.ManagedThreadId.ToString(); 
    });
    //会等到任务执行完之后执行
    task.GetAwaiter().OnCompleted(() =>
    {
        Console.WriteLine(task.Result);
    });
    Console.WriteLine("主线程结束");
    Console.Read();
    

    施行结果:

    新葡亰496net 100

    OnCompleted中的代码会在职务实践到位之后实践!

    另外task.ContinueWith()也是多少个首要的法子:

    Console.WriteLine("主线程开始");
    Task<string> task = Task<string>.Run(() => {
        Thread.Sleep(2000); 
        return Thread.CurrentThread.ManagedThreadId.ToString(); 
    });
    
    task.GetAwaiter().OnCompleted(() =>
    {
        Console.WriteLine(task.Result);
    });
    task.ContinueWith(m=>{Console.WriteLine("第一个任务结束啦!我是第二个任务");});
    Console.WriteLine("主线程结束");
    Console.Read();
    

    实行结果:

    新葡亰496net 101

    ContinueWith()方法能够让该后台线程继续实行新的职责。

    Task的利用或许相比灵敏的,大家可以商讨下,好了,以上正是全体内容了,篇幅和工夫都简单,希望对大家有用!

     

    本文由新葡亰496net发布于奥门新萄京娱乐场,转载请注明出处:的那些事儿,Net异步实例讲解

    关键词:

上一篇:人生苦短,Playbook自动化运维项目实战

下一篇:没有了