轉(zhuǎn)帖|其它|編輯:郝浩|2011-03-11 10:37:41.000|閱讀 878 次
概述:在項目中時常會運(yùn)行很多極其復(fù)雜的算法之后再更新UI控件,可是我們發(fā)現(xiàn)這會耗費(fèi)大量的時間,幾乎讓UI進(jìn)程假死。有什么辦法可以讓程序在后臺完成這些復(fù)雜的算法,當(dāng)算法完成的時候再去更新UI控件以避免UI進(jìn)程假死的情況呢?對了,多線程技術(shù)!后臺創(chuàng)建一個線程來進(jìn)行復(fù)雜計算,就可以不耽誤UI線程更新 UI控件。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
在項目中時常會運(yùn)行很多極其復(fù)雜的算法之后再更新UI控件,可是我們發(fā)現(xiàn)這會耗費(fèi)大量的時間,幾乎讓UI進(jìn)程假死。有什么辦法可以讓程序在后臺完成這些復(fù)雜的算法,當(dāng)算法完成的時候再去更新UI控件以避免UI進(jìn)程假死的情況呢?對了,多線程技術(shù)!后臺創(chuàng)建一個線程來進(jìn)行復(fù)雜計算,就可以不耽誤UI線程更新UI控件。可是如果直接在線程執(zhí)行的函數(shù)里面去更新UI控件則會報“跨線程訪問無效”的錯誤提示。下例中前臺XAML文件里有兩個UI控件label1和label2,在這里通過調(diào)用this.label1.Dispatcher.BeginInvoke方法執(zhí)行l(wèi)abelInvoke委托的函數(shù)UpdateLabel(string content),在UpdateLabel函數(shù)里面就可以直接更新lable1控件需要顯示的內(nèi)容,同理可以更新其他的UI控件的顯示。
下面我們看一下如何在自創(chuàng)建的后臺線程里面更新UI線程的label1控件:
#region 啟動一個無參數(shù)的只負(fù)責(zé)更新UI線程的自定義后臺線程
public void NoParamThread()
{
Thread thread = new Thread(ShowStr);
thread.IsBackground = true;
thread.Start();
}
/// <summary>
/// 顯示Str的函數(shù)
/// </summary>
public void ShowStr()
{
string content= "無參數(shù)傳遞的線程更新";
//運(yùn)行l(wèi)abelInvoke委托的方法UpdateLabel,并且傳遞參數(shù)content
this.label1.Dispatcher.BeginInvoke(new labelInvoke(UpdateLabel),content);
}
/// <summary>
/// 更新Label的委托
/// </summary>
/// <param name="content"></param>
public delegate void labelInvoke(string content);
/// <summary>
/// 更新label1的方法
/// </summary>
/// <param name="content"></param>
public void UpdateLabel(string content)
{
//更新UI線程上的 this.label1.Content值
this.label1.Content = content;
}
#endregion
某一個函數(shù)運(yùn)行需要2秒,輸入5種不同的參數(shù)得到5個結(jié)果,那么一個線程來做這個事需要10秒。可做一個循環(huán)同時開5個線程運(yùn)算這個函數(shù)并且?guī)雲(yún)?shù),那么一共只需要2秒即可,這就是后臺的多線程并行任務(wù)。
下面請看如何來創(chuàng)建多個線程執(zhí)行并行任務(wù)。首先循環(huán)創(chuàng)建5個線程,再為每個線程傳入一個參數(shù),但直接創(chuàng)建線程是無法傳遞參數(shù)的!這些參數(shù)如何傳輸進(jìn)入線程執(zhí)行的函數(shù)內(nèi)部呢?在這里我們使用Thread thread = new Thread(new ParameterizedThreadStart(ShowString));的ParameterizedThreadStart對象來傳遞如參數(shù)。這樣在線程的實例中運(yùn)行thread.Start(object obj)重載函數(shù)即可傳遞一個參數(shù)。
#region 啟動傳遞一個參數(shù)的進(jìn)程
public void HaveParamThread(string str)
{
//循環(huán)創(chuàng)建5個線程
for (int i = 0; i < 5; i++)
{
Thread thread = new Thread(new ParameterizedThreadStart(ShowString));
thread.IsBackground = true;
thread.Start(str + i.ToString());
}
}
/// <summary>
/// 顯示Str的函數(shù)
/// </summary>
public void ShowString(object content)
{
string con = content as string;
//做復(fù)雜運(yùn)算
string strcon = con.Substring(0, con.Length - 2);
//運(yùn)行l(wèi)abelInvoke委托的方法labelDelegete,并且傳遞參數(shù)con
this.label2.Dispatcher.BeginInvoke(new labelDelegete(UpdateLab), con);
}
/// <summary>
/// 更新Label2的委托
/// </summary>
/// <param name="content"></param>
public delegate void labelDelegete(string content);
/// <summary>
/// 更新label2的方法
/// </summary>
/// <param name="content"></param>
public void UpdateLab(string content)
{
//更新UI線程上的 this.label1.Content值
this.label2.Content =this.label2.Content+ "--"+ content;
}
#endregion
通過上面的實例,我們可以總結(jié)出在Silverlight中多線程技術(shù)通常用于以下兩個方面。
第一、加快UI控件響應(yīng),提高用戶體驗。通過UI線程和后臺計算線程的分離,后臺線程專注于計算, 計算完畢將結(jié)果推給前臺UI線程顯示出來。
第二、后臺多任務(wù)并行運(yùn)算。同時開多個線程運(yùn)行不同參數(shù)的一個復(fù)雜計算函數(shù)以節(jié)約計算時間。
本實例采用VS2010+Silverlight 4.0編寫。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:網(wǎng)絡(luò)轉(zhuǎn)載