同步,异步,多线程,你怎么看?
講解同步與異步的帖子多如牛毛,個(gè)人的理解,簡(jiǎn)單地說(shuō)同步就是串行,異步就是并行。同步的情況下,A調(diào)用B,A等B執(zhí)行完成后接著執(zhí)行,自始至終只有一個(gè)線程在運(yùn)行;而異步時(shí),A調(diào)用B,B執(zhí)行,A也繼續(xù)執(zhí)行,這個(gè)過(guò)程中有兩個(gè)線程在運(yùn)行。本文通過(guò)winform下的一個(gè)實(shí)例講解同步與異步的差別,本文的例子很簡(jiǎn)單,適合初學(xué)者。
1.同步
大家應(yīng)該經(jīng)常碰到這種情況,點(diǎn)擊界面上某個(gè)按鈕或者某個(gè)控件后界面卡死的情況,個(gè)人覺(jué)得其中一個(gè)原因可能是主線程的問(wèn)題,界面主線程在后臺(tái)處理其他任務(wù),沒(méi)法同時(shí)響應(yīng)用戶的操作。看一個(gè)最簡(jiǎn)單的例子,界面如下:
代碼:
private void btnCalc_Click(object sender, EventArgs e) ???????
{ ???????????
int sum = Calc(100); ???????????
rtxtMain.Text = "calc over, result is " + sum; ???????????
MessageBox.Show("計(jì)算完成", "提示"); ???????
}
??????? private int Calc(int n) ???????
{ ???????????
int sum = 0; ???????????
Thread.Sleep(TimeSpan.FromSeconds(20)); ???????????
for (int i = 0; i < n; i++) ???????????
{ ???????????????
sum += i; ???????????
} ???????????
return sum; ???????
}
很明顯,使用這種方法時(shí)點(diǎn)擊按鈕后界面就卡住,直到后臺(tái)方法執(zhí)行完才響應(yīng)。原因是只有主線程在運(yùn)行,那么咱們?cè)僦匦缕鹨粋€(gè)新線程,可以自己另起一個(gè)線程,或者使用.NET提供的異步方法。
?
2.異步
.NET異步時(shí)重新從線程池中啟動(dòng)了一個(gè)線程,本例中這個(gè)線程負(fù)責(zé)執(zhí)行后臺(tái)的方法,界面主線程繼續(xù)響應(yīng)用戶的操作。線程池線程執(zhí)行完后臺(tái)方法后彈出提示框提示主線程工作已做完。代碼如下:
public delegate int CalcEventHandler(int n);???? //定義委托
??? public partial class MainFrm : Form ???
{ ???????
public MainFrm() ???????
{ ???????????
InitializeComponent(); ???????????
Control.CheckForIllegalCrossThreadCalls = false;????????? //禁用非法跨線程調(diào)用檢查
}
??????? private void btnCalc_Click(object sender, EventArgs e) ???????
{ ???????????
CalcEventHandler mycalc = new CalcEventHandler(Calc); ???????????
AsyncCallback async = new AsyncCallback(OnComplete);???????????? //回調(diào)方法
mycalc.BeginInvoke(100, async, "this is your data" );????????????????? //執(zhí)行異步
}
??????? private int Calc(int n) ???????
{ ???????????
int sum = 0; ???????????
Thread.Sleep(TimeSpan.FromSeconds(20)); ???????????
for (int i = 0; i < n; i++) ???????????
{ ???????????????
sum += i; ???????????
} ???????????
return sum; ???????
}
//異步完成后執(zhí)行的回調(diào)方法
??????? private void OnComplete(IAsyncResult asycResult) ???????
{ ???????????
AsyncResult result = (AsyncResult)asycResult; ???????????
CalcEventHandler del = (CalcEventHandler)result.AsyncDelegate;??????//向下轉(zhuǎn)換??????
int sum = del.EndInvoke(asycResult);?????//獲取返回值???????????
string data = result.AsyncState != null ? result.AsyncState.ToString() : string.Empty;???????????//獲取傳遞的數(shù)據(jù)
? rtxtMain.Text = "calc over, 結(jié)果為 " + sum + ", 傳遞信息為 " + data; ???????????
MessageBox.Show("計(jì)算完成","提示");?????????//提示主線程
} ???
}
結(jié)果如下:
這樣,界面不會(huì)出現(xiàn)卡死的情況,可以提高用戶體驗(yàn)。當(dāng)然這只是一個(gè)簡(jiǎn)單的例子。
?
還有一種方法就是,自己另外啟一個(gè)線程,代碼如下:
private void btnCalc_Click(object sender, EventArgs e) ???????
{??????????????
Thread tr = new Thread(new ThreadStart(Calc));???????//啟動(dòng)新線程??????
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, 結(jié)果為 " + sum;???????????? //提示移到這里
MessageBox.Show("計(jì)算完成", "提示"); ??????????
? return sum; ???????
}
?
?
小結(jié):
1.這個(gè)例子很簡(jiǎn)單,用于了解同步和異步的區(qū)別和作用。
? 2.同步和異步跟為委托和多線程是相關(guān)聯(lián)的,有興趣的朋友繼續(xù)學(xué)習(xí)委托和多線程相關(guān)知識(shí)。
?
本文寫(xiě)的很簡(jiǎn)單,謝謝你的閱讀,如果有好的建議或方法,歡迎留言,一起交流~~
?
?
?
?
?
posted on 2014-03-14 15:27 NET未來(lái)之路 閱讀(...) 評(píng)論(...) 編輯 收藏轉(zhuǎn)載于:https://www.cnblogs.com/lonelyxmas/p/3600676.html
總結(jié)
以上是生活随笔為你收集整理的同步,异步,多线程,你怎么看?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 安装 Tableau Desktop 时
- 下一篇: 【job】2013年5-5阿里巴巴暑期实