同步,异步,多线程,你怎么看?

原文:同步,异步,多线程,你怎么看?[原创]

  讲解同步与异步的帖子多如牛毛,个人的理解,简单地说同步就是串行,异步就是并行。同步的情况下,A调用B,A等B执行完成后接着执行,自始至终只有一个线程在运行;而异步时,A调用B,B执行,A也继续执行,这个过程中有两个线程在运行。本文通过winform下的一个实例讲解同步与异步的差别,本文的例子很简单,适合初学者。

  1.同步

  大家应该经常碰到这种情况,点击界面上某个按钮或者某个控件后界面卡死的情况,个人觉得其中一个原因可能是主线程的问题,界面主线程在后台处理其他任务,没法同时响应用户的操作。看一个最简单的例子,界面如下:

  

同步,异步,多线程,你怎么看?

代码:

private void btnCalc_Click(object sender, EventArgs e)        

{            

   int sum = Calc(100);            

  rtxtMain.Text = "calc over, result is " + sum;            

  MessageBox.Show("计算完成", "提示");        

}

        private int Calc(int n)        

{            

  int sum = 0;            

  Thread.Sleep(TimeSpan.FromSeconds(20));            

  for (int i = 0; i < n; i++)            

  {                

    sum += i;            

  }            

  return sum;        

}

  很明显,使用这种方法时点击按钮后界面就卡住,直到后台方法执行完才响应。原因是只有主线程在运行,那么咱们再重新起一个新线程,可以自己另起一个线程,或者使用.NET提供的异步方法。

 

  2.异步

  .NET异步时重新从线程池中启动了一个线程,本例中这个线程负责执行后台的方法,界面主线程继续响应用户的操作。线程池线程执行完后台方法后弹出提示框提示主线程工作已做完。代码如下:

  

  

  public delegate int CalcEventHandler(int n);     //定义委托

    public partial class MainFrm : Form    

  {        

    public MainFrm()        

     {            

      InitializeComponent();            

      Control.CheckForIllegalCrossThreadCalls = false;          //禁用非法跨线程调用检查

    }

          private void btnCalc_Click(object sender, EventArgs e)        

    {            

      CalcEventHandler mycalc = new CalcEventHandler(Calc);            

      AsyncCallback async = new AsyncCallback(OnComplete);             //回调方法

      mycalc.BeginInvoke(100, async, "this is your data" );                  //执行异步

    }

        private int Calc(int n)        

    {            

      int sum = 0;            

      Thread.Sleep(TimeSpan.FromSeconds(20));            

      for (int i = 0; i < n; i++)            

      {                

        sum += i;            

      }            

      return sum;        

    }

   //异步完成后执行的回调方法

        private void OnComplete(IAsyncResult asycResult)        

   {            

    AsyncResult result = (AsyncResult)asycResult;            

    CalcEventHandler del = (CalcEventHandler)result.AsyncDelegate;      //向下转换      

    int sum = del.EndInvoke(asycResult);     //获取返回值           

    string data = result.AsyncState != null ? result.AsyncState.ToString() : string.Empty;           //获取传递的数据

     rtxtMain.Text = "calc over, 结果为 " + sum + ", 传递信息为 " + data;            

    MessageBox.Show("计算完成","提示");         //提示主线程

  }    

}

结果如下:

同步,异步,多线程,你怎么看?

  这样,界面不会出现卡死的情况,可以提高用户体验。当然这只是一个简单的例子。

 

  还有一种方法就是,自己另外启一个线程,代码如下:

  private void btnCalc_Click(object sender, EventArgs e)        

  {              

    Thread tr = new Thread(new ThreadStart(Calc));       //启动新线程      

    tr.Start();        

  }

        private void Calc()      //重载方法   

  {            

    Calc(100);        

  }

       

  private int Calc(int n)        

  {            

    int sum = 0;            

    Thread.Sleep(TimeSpan.FromSeconds(5));            

    for (int i = 0; i < n; i++)            

    {                

      sum += i;            

    }            

    rtxtMain.Text = "calc over, 结果为 " + sum;             //提示移到这里

    MessageBox.Show("计算完成", "提示");           

    return sum;        

  }

 

 

小结:

  1.这个例子很简单,用于了解同步和异步的区别和作用。

   2.同步和异步跟为委托和多线程是相关联的,有兴趣的朋友继续学习委托和多线程相关知识。

 

本文写的很简单,谢谢你的阅读,如果有好的建议或方法,欢迎留言,一起交流~~

同步,异步,多线程,你怎么看?,布布扣,bubuko.com

同步,异步,多线程,你怎么看?

上一篇:php保存文件和下载文件到本地的四种方法


下一篇:Kubernetes(一)