講解同步與異步的文章多如牛毛,個人的了解,簡單地說同步就是串行,異步就是并行。同步的情況下,A調用B,A等B執行完成後接着執行,自始至終隻有一個線程在運作;而異步時,A調用B,B執行,A也繼續執行,這個過程中有兩個線程在運作。本文通過winform下的一個執行個體講解同步與異步的差别,本文的例子很簡單,适合初學者。
1.同步
大家應該經常碰到這種情況,點選界面上某個按鈕或者某個控件後界面卡死的情況,個人覺得其中一個原因可能是主線程的問題,界面主線程在背景處理其他任務,沒法同時響應使用者的操作。看一個最簡單的例子,界面如下:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiInBnauMzMxQTZkRzMhdDMxUDMyEWYwIWYwQDMxgDN4EjMidTYfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.jpg)
代碼:
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" ); //執行異步
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.同步和異步跟為委托和多線程是相關聯的,有興趣的朋友繼續學習委托和多線程相關知識。
本文寫的很簡單,謝謝你的閱讀,如果有好的建議或方法,歡迎留言,一起交流~~