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

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

  讲解同步与异步的帖子多如牛毛,个人的理解,简单地说同步就是串行,异步就是并行。同步的情况下,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.同步和异步跟为委托和多线程是相关联的,有兴趣的朋友继续学习委托和多线程相关知识。

 

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

 

 

 

 

 

posted on 2014-03-14 15:27 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/3600676.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/432781.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

openssl-1.0.0b - libssl 移植到ARM Linux

开发环境&#xff1a; ubuntu 10.04 arm-linux-gcc version 4.4.1 目标环境 友善之臂mini6410 linux-2.6.36 移植步骤 1&#xff0e;至官网下载最新的openssl&#xff0c;解压缩 2&#xff0e;cd进入openssl-1.0.0b目录 3&#xff0e;执行./Confiugre linux-elf-arm&#xff0c…

C语言的putpiel函数,C语言graphics.h函数介绍

可编辑(一) 像素函数56. putpiel() 画像素点函数57. getpixel()返回像素色函数(二) 直线和线型函数58. line() 画线函数59. lineto() 画线函数60. linerel() 相对画线函数61. setlinestyle() 设置线型函数62. getlinesettings() 获取线型设置函数63. setwritemode() 设置画线模…

ARM-Linux下交叉编译opessl-1.0.0

本次任务是要完成嵌入式Linux下对openssl程序的支持。 我的开发环境&#xff1a;ARM9开发板 和 嵌入式Linux操作系统。装有Linux系统&#xff08;我的是ubuntu9.04&#xff09;的PC机一台。串口和串口连接线。串口调试软件&#xff1a;minicom。交叉编译工具:arm-unknown-l…

modf函数C语言,C / C ++中的modf()

该函数modf()用于将传递的参数拆分为整数和小数。在“ math.h”头文件中声明该变量以进行数学计算。它返回传递的参数的分数值。这是modf()C语言的语法&#xff0c;double modf(double value, double *integral_pointer);这里&#xff0c;值-分为整数和分数的值。积分指针-分割…

codeforces #236 div2 简洁题解

A:A. Nutstime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard outputYou have a nuts and lots of boxes. The boxes have a wonderful feature: if you put x (x ≥ 0)divisors (the spacial bars that can divide a box) to…

南京大学c语言试卷,2007年4月南京大学C语言期中试题.doc

2007年4月南京大学C语言期中试题南京大学《C语言程序设计》期中试卷(2006年4月15日)系科 学号______________姓名_____________成绩_______________注意事项&#xff1a;1、答案均写在答题纸上&#xff0c;写在卷面上无效;2、答题结束后将试卷及答题纸全部交给监考教师;3、闭卷…

web通信 长连接、长轮询

http://www.cnblogs.com/hoojo/p/longPolling_comet_jquery_iframe_ajax.html转载于:https://www.cnblogs.com/kszit/p/3605340.html

V210 SPI驱动分析

对于总线设备驱动&#xff0c;是需要分别创建设备和驱动两个结构体&#xff0c;然后根据name&#xff0c;互相匹配&#xff0c;匹配成功后&#xff0c;调用 驱动的probe函数&#xff0c;然后创建设备文件&#xff0c;实现驱动的业务逻辑。 因此&#xff0c;我们就以设备和驱动…

android 有值代码,Android:如何在代码中获取“listPreferredItemHeight”属性的值?

这样做&#xff1a;TypedValue value new TypedValue();((Activity)context).getTheme().resolveAttribute(android.R.attr.listPreferredItemHeight, value, true);编辑&#xff1a;由于尚未正确初始化DisplayMetrics实例&#xff0c;因此您将获得零值。它需要一个参考框架(显…

android 多个按钮响应,处理Android Recyclerview中的多个按钮单击并将响应存储在Array或ArrayList中...

我正在设计在线测验App。我设计了PlayQuiz.java文件如下&#xff1a;public class PlayQuiz extends AppCompatActivity {private RecyclerView recyclerView;DataBaseHelper database;private List quizList;private QuizAdapter adapter;Overrideprotected void onCreate(Bun…

密码学中的“盐值 Salt”

盐&#xff08;Salt&#xff09; 在密码学中&#xff0c;是指通过在密码任意固定位置插入特定的字符串&#xff0c;让散列后的结果和使用原始密码的散列结果不相符&#xff0c;这种过程称之为“加盐”。 以上这句话是维基百科上对于 Salt 的定义&#xff0c;但是仅凭这句话还是…

android 主线程调用,Android 主线程和线程之间相互发送消息

通过分析Activity源码&#xff0c;我们知道每个Activity都有一个Looper&#xff0c;所以主线程在接收Message是不需要调用Looper.prepare()和Looper.loop()&#xff0c;但是线程是不带Looper的&#xff0c;当线程要接收来自主线程的消息是就需要调用Looper.prepare()和Looper.l…

10 个十分难得的 javascript 开发经验

Javascript 的很多扩展的特性是的它变得更加的犀利&#xff0c; 同时也给予程序员机会创建更漂亮并且更让用户喜欢的网站。 尽管很多的开发人员都乐于颂扬 javascript&#xff0c;但是仍旧有人看到它的阴暗面。 使用很多 javascript 代码的 web 页面会加载很慢&#xff0c;过多…

简单的UTF8编码生成

用记事本建一个文件&#xff0c;用editplus打开&#xff0c;并转成UTF8格式 然后写中文字符 然后用ultraEdit打开&#xff0c;切换到16机制模式即可

android unzip file,Unzip File in Android Assets

可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效&#xff0c;请关闭广告屏蔽插件后再试):问题:I put a zip file in the android assets. How do i extract the file in the android internal storage? I know how to get the file, but i dont know how t…

Eclipse安装ADT失败解决办法

Eclipse的版本是3.5.2&#xff0c;配置Android的开发环境时遇到问题…… 按照Android官方文档一步步安装&#xff0c;到了安装Eclipse的ADT插件时&#xff0c;提示“requires org.eclipse.gef 0.0.0 but it could not be found” 缺少GEF&#xff0c;Eclipses Graphic Editing …

DM3730 LCD控制器驱动框架

一般来说&#xff0c;linux的LCD控制器驱动是分两个层次 1) fbmem.c 一个linux内核通用的LCD控制器层&#xff0c;没有任何硬件信息&#xff0c;而且不创建设备文件。 它提供的最重要的接口函数是register_framebuffer 2) 特定芯片的LCD控制器硬件驱动代码&#xff0c;他来调…

html仿qq最小化怎么实现,JS仿QQ好友列表展开、收缩功能(第一篇)

JS仿QQ好友列表展开、收缩功能(第一篇)发布时间&#xff1a;2020-10-17 14:20:03来源&#xff1a;脚本之家阅读&#xff1a;96作者&#xff1a;erdouzhang效果图如下所示&#xff1a;html:我的好友张三李四...企业好友小明小红...黑名单哈哈...css&#xff1a;ul,h3 {padding: …

Visual Studio 选择相同变量高亮

前段时间一直在使用matlab&#xff0c;今天需要使用vs2008&#xff0c;而用惯了matlab&#xff0c;习惯了其中一项选中变量高亮的设置&#xff0c;突然回来使用VS&#xff0c;感到各种不适应&#xff0c;顿时想到了一个词&#xff1a;矫情 呵呵&#xff0c;于是在网上找各种插件…

V210调整根分区大小

1. 修改uboot common/mmc_cmd_fdisk.c #define SYSTEM_PART_SIZE (120*1024*1024) 将120改成256 2. 在dd文件系统的时候&#xff0c;增大count dd if/dev/zero ofrootfs_qt4.ext3 bs1024 count262144 重烧系统的时候&#xff0c;需要先烧入uboot&#xff0c;然后重启再烧入…