zoukankan      html  css  js  c++  java
  • 异步Async

      1 using System;
      2 using System.Collections.Generic;
      3 using System.ComponentModel;
      4 using System.Data;
      5 using System.Diagnostics;
      6 using System.Drawing;
      7 using System.Linq;
      8 using System.Text;
      9 using System.Threading;
     10 using System.Windows.Forms;
     11 
     12 namespace 异步Async
     13 {
     14     /*
     15      * 1.同步启动时会卡主界面,异步不会,原因是异步调用了子线程去执行,使主线程得到释放
     16      * 2.同步方法慢,异步方法快,启动多线程,占用更多资源
     17      * 3.异步是无序的
     18      */
     19     public partial class Form1 : Form
     20     {
     21         public Form1()
     22         {
     23             InitializeComponent();
     24         }
     25 
     26         
     27         private Action<string> act; //定义一个无返回结果委托
     28         private Func<string, long> func; //定义一个有返回结果委托
     29 
     30         /// <summary>
     31         /// 异步调用
     32         /// </summary>
     33         /// <param name="sender"></param>
     34         /// <param name="e"></param>
     35         private void btnAsync_Click(object sender, EventArgs e)
     36         {
     37             //act = t => Console.WriteLine("别跟我BB,{0},当前线程是{1}",t,Thread.CurrentThread.ManagedThreadId);
     38             //act.BeginInvoke("你大爷还是你大爷",null,null);
     39 
     40             //将DoSomething方法执行5次
     41             Console.WriteLine("*****************异步方法btnAsync_Click****************");
     42             
     43             for (int i = 0; i < 5; i++)
     44             {
     45                 act = DoSomething; //需要结合委托使用
     46                 act.BeginInvoke("异步", null, null); //异步启动多个线程调用DoSomething()方法
     47                 //第一个参数为DoSomething()方法的name参数,第二为回调函数,第三为回调函数的状态参数
     48             }
     49             Console.WriteLine("*****************异步方法btnAsync_Click****************");
     50             Console.WriteLine("
    ");
     51         }
     52 
     53         /// <summary>
     54         /// 异步进阶
     55         /// </summary>
     56         /// <param name="sender"></param>
     57         /// <param name="e"></param>
     58         private void btnAsyncAdvanced_Click(object sender, EventArgs e)
     59         {
     60             Console.WriteLine("*****************异步进阶btnAsync_Click****************");
     61             act = DoSomething; 
     62 
     63             AsyncCallback back = t => Console.WriteLine("这里是回调函数,当前线程ID是{0},AsyncState为{1}",Thread.CurrentThread.ManagedThreadId,t.AsyncState);
     64 
     65             IAsyncResult result= act.BeginInvoke("异步回调", back, "回调参数param思密达"); //异步回调,添加回调参数
     66 
     67             /*
     68             //异步等待1
     69             result.AsyncWaitHandle.WaitOne(-1); //主线程无限期等待子线程结束,相当于回到同步
     70 
     71             //异步等待2,可以做进度条
     72             while (!result.IsCompleted)
     73             {
     74                 Thread.Sleep(100);
     75                 Console.WriteLine("请继续等待.......");
     76             }
     77 
     78             //异步等待3
     79             act.EndInvoke(result);
     80             */
     81 
     82             Console.WriteLine("*****************异步进阶btnAsync_Click****************");
     83             Console.WriteLine("
    ");
     84         }
     85 
     86         /// <summary>
     87         /// 异步进阶2,调用有返回结果的方法
     88         /// </summary>
     89         /// <param name="sender"></param>
     90         /// <param name="e"></param>
     91         private void btnAsyncAdv2_Click(object sender, EventArgs e)
     92         {
     93             Console.WriteLine("*****************异步进阶2btnAsync_Click****************");
     94             func = GetDoSomething;
     95 
     96             /*第一种异步等待等到该GetDoSomething()方法的返回结果,但是会卡住主线程
     97 
     98              IAsyncResult result = func.BeginInvoke("异步进阶2", t =>Console.WriteLine("这里是回调函数,当前线程ID是{0},AsyncState为{1}", Thread.CurrentThread.ManagedThreadId, t.AsyncState), "哈哈哈param");
     99 
    100 
    101              在等待的过程中可以做别的很多事........
    102              这里可以调用其它方法
    103 
    104 
    105             long r = func.EndInvoke(result);
    106             Console.WriteLine("sum的结果为:{0}",r);
    107 
    108             */
    109 
    110             //第二种异步等待结果,直接将等待方法EndInvoke()写入回调函数中,注:拉姆达表达式的匿名函数可以写成 new AsyncCallback(回调函数名),该函数需加参数(IAsyncResult result)
    111 
    112             //注:t为得到的result,第二种的好处是不会卡住主线程,因为异步等待在子线程中运行
    113             IAsyncResult result = func.BeginInvoke("异步进阶2", t =>
    114             {
    115                 Console.WriteLine("这里是回调函数,当前线程ID是{0},AsyncState为{1}", Thread.CurrentThread.ManagedThreadId, t.AsyncState);
    116 
    117                 //在这里直接得到GetDoSomething()方法的返回结果,6不6
    118                 long r = func.EndInvoke(t);
    119                 Console.WriteLine("sum的结果为:{0}",r);
    120             }, "哈哈哈param");
    121 
    122 
    123             //下面在等待过程中可以做别的很多事.......
    124             //可以调用其它方法,如:
    125             Console.WriteLine("这里可以做别的事儿......");
    126               
    127 
    128             Console.WriteLine("*****************异步进阶2btnAsync_Click****************");
    129         }
    130 
    131         /// <summary>
    132         /// 同步调用
    133         /// </summary>
    134         /// <param name="sender"></param>
    135         /// <param name="e"></param>
    136         private void btnSync_Click(object sender, EventArgs e)
    137         {
    138             //将DoSomething执行5次
    139             Console.WriteLine("*****************同步方法btnSync_Click****************");
    140             for (int i = 0; i < 5; i++)
    141             {
    142                 DoSomething("同步");
    143             }
    144             Console.WriteLine("*****************同步方法btnSync_Click****************");
    145             Console.WriteLine("
    ");
    146         }
    147 
    148         /// <summary>
    149         /// 耗时void无返回结果方法
    150         /// </summary>
    151         /// <param name="name"></param>
    152         private void DoSomething(string name)
    153         {
    154             //监控此方法所用时间
    155             Stopwatch watch = new Stopwatch();
    156             watch.Start();
    157             Console.WriteLine("当前是{0}在调用次方法,当前线程ID是{1}",name,Thread.CurrentThread.ManagedThreadId);
    158             long sum = 0;
    159             for (int i = 0; i < 1000000000; i++)
    160             {
    161                 sum += i;
    162             }
    163             Thread.Sleep(1000); //等待1秒
    164             watch.Stop();
    165             Console.WriteLine("sum结果是:{0},耗时{1}", sum, watch.ElapsedMilliseconds);
    166         }
    167 
    168         /// <summary>
    169         /// 有返回结果的方法
    170         /// </summary>
    171         /// <param name="name"></param>
    172         /// <returns></returns>
    173         private long GetDoSomething(string name)
    174         {
    175             long sum = 0;
    176             for (int i = 0; i < 1000000000; i++)
    177             {
    178                 sum += i;
    179             }
    180             return sum;
    181         }
    182     }
    183 }
    世界上最可怕事情是比我们优秀的人比我们还努力
  • 相关阅读:
    多线程、方便扩展的Windows服务程序框架
    C#并行开发_Thread/ThreadPool, Task/TaskFactory, Parallel
    C#并行编程-Task
    C#线程篇---Task(任务)和线程池不得不说的秘密(5)
    C# 线程知识--使用Task执行异步操作
    C# 线程池执行操作例子
    c#子线程执行完怎么通知主线程
    C#子线程执行完后通知主线程
    再送一波干货,测试2000线程并发下同时查询1000万条数据库表及索引优化
    熵的函数为什么用H,而熵的英文是entropy,好像没关系。实际原因是
  • 原文地址:https://www.cnblogs.com/AlexOneBlogs/p/7282996.html
Copyright © 2011-2022 走看看