C# 同步异步
同步,即CPU在执行一个任务的同时,不能执行其他任务,只有等待原有任务完成后,才能执行新的任务。
异步:当CPU在执行一个的任务的时候,可以同时执行其他任务。任务之间不会相互干扰。
下面源码,给出了同步和异步之间的区别:
设计器代码:
1 namespace AsynExam 2 { 3 partial class Form_Syn_Asyn 4 { 5 /// <summary> 6 /// 必需的设计器变量。 7 /// </summary> 8 private System.ComponentModel.IContainer components = null; 9 10 /// <summary> 11 /// 清理所有正在使用的资源。 12 /// </summary> 13 /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param> 14 protected override void Dispose(bool disposing) 15 { 16 if (disposing && (components != null)) 17 { 18 components.Dispose(); 19 } 20 base.Dispose(disposing); 21 } 22 23 #region Windows 窗体设计器生成的代码 24 25 /// <summary> 26 /// 设计器支持所需的方法 - 不要 27 /// 使用代码编辑器修改此方法的内容。 28 /// </summary> 29 private void InitializeComponent() 30 { 31 this.textBox = new System.Windows.Forms.TextBox(); 32 this.btnAsyncCall = new System.Windows.Forms.Button(); 33 this.btnSyncCall = new System.Windows.Forms.Button(); 34 this.paintBox = new System.Windows.Forms.PictureBox(); 35 this.btnClear = new System.Windows.Forms.Button(); 36 this.lblMsg = new System.Windows.Forms.Label(); 37 ((System.ComponentModel.ISupportInitialize)(this.paintBox)).BeginInit(); 38 this.SuspendLayout(); 39 // 40 // textBox 41 // 42 this.textBox.Location = new System.Drawing.Point(13, 13); 43 this.textBox.Multiline = true; 44 this.textBox.Name = "textBox"; 45 this.textBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; 46 this.textBox.Size = new System.Drawing.Size(275, 274); 47 this.textBox.TabIndex = 0; 48 // 49 // btnAsyncCall 50 // 51 this.btnAsyncCall.Location = new System.Drawing.Point(346, 25); 52 this.btnAsyncCall.Name = "btnAsyncCall"; 53 this.btnAsyncCall.Size = new System.Drawing.Size(97, 23); 54 this.btnAsyncCall.TabIndex = 1; 55 this.btnAsyncCall.Text = "异步调用(&A)"; 56 this.btnAsyncCall.UseVisualStyleBackColor = true; 57 this.btnAsyncCall.Click += new System.EventHandler(this.btnAsyncCall_Click); 58 // 59 // btnSyncCall 60 // 61 this.btnSyncCall.Location = new System.Drawing.Point(346, 66); 62 this.btnSyncCall.Name = "btnSyncCall"; 63 this.btnSyncCall.Size = new System.Drawing.Size(97, 23); 64 this.btnSyncCall.TabIndex = 2; 65 this.btnSyncCall.Text = "同步调用(&S)"; 66 this.btnSyncCall.UseVisualStyleBackColor = true; 67 this.btnSyncCall.Click += new System.EventHandler(this.btnSyncCall_Click); 68 // 69 // paintBox 70 // 71 this.paintBox.BackColor = System.Drawing.Color.White; 72 this.paintBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; 73 this.paintBox.Location = new System.Drawing.Point(312, 108); 74 this.paintBox.Name = "paintBox"; 75 this.paintBox.Size = new System.Drawing.Size(173, 179); 76 this.paintBox.TabIndex = 3; 77 this.paintBox.TabStop = false; 78 this.paintBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.paintBox_MouseMove); 79 this.paintBox.MouseDown += new System.Windows.Forms.MouseEventHandler(this.paintBox_MouseDown); 80 // 81 // btnClear 82 // 83 this.btnClear.Location = new System.Drawing.Point(346, 300); 84 this.btnClear.Name = "btnClear"; 85 this.btnClear.Size = new System.Drawing.Size(97, 23); 86 this.btnClear.TabIndex = 4; 87 this.btnClear.Text = "&Clear"; 88 this.btnClear.UseVisualStyleBackColor = true; 89 this.btnClear.Click += new System.EventHandler(this.btnClear_Click); 90 // 91 // lblMsg 92 // 93 this.lblMsg.AutoSize = true; 94 this.lblMsg.Font = new System.Drawing.Font("宋体", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); 95 this.lblMsg.Location = new System.Drawing.Point(91, 298); 96 this.lblMsg.Name = "lblMsg"; 97 this.lblMsg.Size = new System.Drawing.Size(69, 20); 98 this.lblMsg.TabIndex = 5; 99 this.lblMsg.Text = "label1"; 100 // 101 // Form_Syn_Asyn 102 // 103 this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 104 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 105 this.ClientSize = new System.Drawing.Size(509, 336); 106 this.Controls.Add(this.lblMsg); 107 this.Controls.Add(this.btnClear); 108 this.Controls.Add(this.paintBox); 109 this.Controls.Add(this.btnSyncCall); 110 this.Controls.Add(this.btnAsyncCall); 111 this.Controls.Add(this.textBox); 112 this.Name = "Form_Syn_Asyn"; 113 this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 114 this.Text = "同步操作与异步操作"; 115 ((System.ComponentModel.ISupportInitialize)(this.paintBox)).EndInit(); 116 this.ResumeLayout(false); 117 this.PerformLayout(); 118 119 } 120 121 #endregion 122 123 private System.Windows.Forms.TextBox textBox; 124 private System.Windows.Forms.Button btnAsyncCall; 125 private System.Windows.Forms.Button btnSyncCall; 126 private System.Windows.Forms.PictureBox paintBox; 127 private System.Windows.Forms.Button btnClear; 128 private System.Windows.Forms.Label lblMsg; 129 } 130 }
以下是后台代码:
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Text; 7 using System.Windows.Forms; 8 9 namespace AsynExam 10 { 11 public partial class Form_Syn_Asyn : Form 12 { 13 // 声明更新用户界面委托 14 public delegate string delegateUpdateUI(); 15 16 delegateUpdateUI du; // 委托实例变量 17 string genStr; // 随机数字串 18 19 public Form_Syn_Asyn() 20 { 21 InitializeComponent(); 22 lblMsg.Text = ""; 23 } 24 25 // 在画板上画画线 26 int x, y; // 线段上一端点坐标 27 private void paintBox_MouseMove(object sender, MouseEventArgs e) 28 { 29 if ((e.Button & MouseButtons.Left) != 0) 30 { 31 Graphics g = paintBox.CreateGraphics(); 32 g.DrawLine(Pens.Red, x, y, e.X, e.Y); 33 x = e.X; 34 y = e.Y; 35 } 36 } 37 38 // 鼠标按下时记下线条起点 39 private void paintBox_MouseDown(object sender, MouseEventArgs e) 40 { 41 x = e.X; 42 y = e.Y; 43 } 44 45 private void btnClear_Click(object sender, EventArgs e) 46 { 47 Graphics g = paintBox.CreateGraphics(); 48 g.Clear(Color.White); 49 textBox.Clear(); 50 } 51 //-------------------------------------------------- 52 53 //************************************************** 54 // 同步调用随机数发生器 55 private void btnSyncCall_Click(object sender, EventArgs e) 56 { 57 RandomNumberGenerator rng = new RandomNumberGenerator(200); 58 lblMsg.Text = "开始生成数据"; 59 textBox.Text = rng.Start(); 60 lblMsg.Text = "生成数据结束"; 61 } 62 63 //-------------------------------------------------- 64 65 //************************************************** 66 // 异步调用随机数发生器 67 private void btnAsyncCall_Click(object sender, EventArgs e) 68 { 69 RandomNumberGenerator rng = new RandomNumberGenerator(200); 70 // 回调委托实例 71 System.AsyncCallback asyncCB = new AsyncCallback(myCallBack); 72 73 // "更新用户界面委托" 实例 74 du = new delegateUpdateUI(rng.Start); 75 // 异步调用 "回调委托" 76 lblMsg.Text = "开始生成数据"; 77 du.BeginInvoke(asyncCB, null); 78 } 79 // 异步回调函数 80 private void myCallBack(System.IAsyncResult ar) 81 { 82 // 异步回调结束 83 genStr = du.EndInvoke(ar); 84 85 // 方法委托实例 86 MethodInvoker mi = new MethodInvoker(this.UpdateUI); 87 // 调用方法委托 88 BeginInvoke(mi); 89 } 90 // 异步回调结束后更新用户界面 91 private void UpdateUI() 92 { 93 textBox.Text = genStr; 94 lblMsg.Text = "生成数据结束"; 95 } 96 //-------------------------------------------------- 97 } 98 // 随机数发生器 99 public class RandomNumberGenerator 100 { 101 int count; 102 public RandomNumberGenerator(int n) 103 { 104 count = n; 105 } 106 public string Start() 107 { 108 System.Random rdm = new Random(); 109 int[] r = new int[count]; 110 for (int i = 0; i < count; i++) // 大约需要 count * 50 ms 111 { 112 r[i] = rdm.Next(100); 113 System.Threading.Thread.Sleep(50); 114 } 115 int ln = 0; 116 string s = ""; 117 for (int i = 0; i < count; i++) 118 { 119 s += string.Format("{0,4}", r[i]); 120 ln = ++ln % 10; 121 if (ln == 0) s += "\r\n"; 122 } 123 return s; 124 } 125 } 126 }
运行效果:
说明:
当点击“异步调用”按钮时候,左侧开始生成数据,大概十几秒钟,在右侧画布中可以用鼠标画连续的线,
当点击“同步调用”按钮的时候,左侧开始生成数据,时间大概十几秒,在右侧画布中不可以画线,否则系统界面会卡住,直到左侧数据生成完成后,右侧方可画线。