国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

c# winform編程之多線程ui界面資源修改總結篇

2019-11-17 03:03:49
字體:
來源:轉載
供稿:網友
c# winform編程之多線程ui界面資源修改總結篇

單線程的winfom程序中,設置一個控件的值是很easy的事情,直接 this.TextBox1.value = "Hello World!";就搞定了,但是如果在一個新線程中這么做,比如:PRivate void btnSet_Click(object sender, EventArgs e){ Thread t = new Thread(new ParameterizedThreadStart(SetTextBoxValue)); //當然也可以用匿名委托寫成Thread t = new Thread(SetTextBoxValue); t.Start("Hello World");}void SetTextBoxValue(object obj){ this.textBox1.Text = obj.ToString();}運行時,會報出一個無情的錯誤:線程間操作無效: 從不是創建控件“textBox1”的線程訪問它。究其原因,winform中的UI控件不是線程安全的,如果可以隨意在任何線程中改變其值,你創建一個線程,我創建一個線程,大家都來搶著更改"TextBox1"的值,沒有任何秩序的話,天下大亂...解決辦法:1.掩耳盜鈴法(Control.CheckForIllegalCrossThreadCalls = false;)--僅Winform有效using System;using System.Threading;using System.Windows.Forms;namespace ThreadTest{ public partial class Form1 : Form { public Form1() { InitializeComponent(); Control.CheckForIllegalCrossThreadCalls = false;//這一行是關鍵 } private void btnSet_Click(object sender, EventArgs e) { Thread t = new Thread(new ParameterizedThreadStart(SetTextBoxValue)); t.Start("Hello World"); } void SetTextBoxValue(object obj) { this.textBox1.Text = obj.ToString(); } }}設置Control.CheckForIllegalCrossThreadCalls為false,相當于不檢測線程之間的沖突,允許各路線程隨便亂搞,當然最終TextBox1的值到底是啥難以預料,只有天知道,不過這也是最省力的辦法2.利用委托調用--最常見的辦法(僅WinForm有效)using System;using System.Threading;using System.Windows.Forms;namespace ThreadTest{ public partial class Form1 : Form { delegate void D(object obj); public Form1() { InitializeComponent(); } private void btnSet_Click(object sender, EventArgs e) { Thread t = new Thread(new ParameterizedThreadStart(SetTextBoxValue)); t.Start("Hello World"); } void SetTextBoxValue(object obj) { if (textBox1.InvokeRequired) { D d = new D(DelegateSetValue); textBox1.Invoke(d,obj); } else { this.textBox1.Text = obj.ToString(); } } void DelegateSetValue(object obj) { this.textBox1.Text = obj.ToString(); } }}3.利用SynchronizationContext上下文 -- 最神秘的方法(Winform/Silverlight能用)之所以說它神秘,是因為msdn官方對它的解釋據說也是不清不楚using System;using System.Threading;using System.Windows.Forms;namespace ThreadTest{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void btnSet_Click(object sender, EventArgs e) { Thread t = new Thread(new ParameterizedThreadStart(Run)); MyPram _p = new MyPram() { context = SynchronizationContext.Current, parm = "Hello World" }; t.Start(_p); } void Run(object obj) { MyPram p = obj as MyPram; p.context.Post(SetTextValue, p.parm); } void SetTextValue(object obj) { this.textBox1.Text = obj.ToString(); } } public class MyPram { public SynchronizationContext context { set; get; } public object parm { set; get; } }}4.利用BackgroundWorker --最偷懶的辦法(Winform/Silverlight通用)BackgroundWorker會在主線程之外,另開一個后臺線程,我們可以把一些處理放在后臺線程中處理,完成之后,后臺線程會把結果傳遞給主線程,同時結束自己。using System;using System.ComponentModel;using System.Windows.Forms;namespace ThreadTest{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void btnSet_Click(object sender, EventArgs e) { //MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString()); using (BackgroundWorker bw = new BackgroundWorker()) { bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); bw.DoWork += new DoWorkEventHandler(bw_DoWork); bw.RunWorkerAsync("Hello World"); } } void bw_DoWork(object sender, DoWorkEventArgs e) { //MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString()); e.Result = e.Argument;//這里只是簡單的把參數當做結果返回,當然您也可以在這里做復雜的處理后,再返回自己想要的結果(這里的操作是在另一個線程上完成的) } void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //這時后臺線程已經完成,并返回了主線程,所以可以直接使用UI控件了 this.textBox1.Text = e.Result.ToString(); //MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString()); } }}5.Dispatcher.BeginInvoke--Silverlight的獨門秘籍代碼using System.Threading;using System.Windows.Controls;using System.Windows.Input;namespace ThreadTest{ public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private void LayoutRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Thread t = new Thread(SetTextValue); t.Start("Hello World"); } void SetTextValue(object text) { this.Dispatcher.BeginInvoke(() => { this.txt.Text = text.ToString(); }); } }}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 丰城市| 平泉县| 新田县| 商南县| 岳池县| 赞皇县| 清新县| 绥阳县| 汶上县| 烟台市| 综艺| 永城市| 宁蒗| 革吉县| 博野县| 和田县| 上思县| 绥滨县| 青岛市| 宜宾县| 涞水县| 平顺县| 香河县| 尉犁县| 青浦区| 和龙市| 漳浦县| 凤山市| 綦江县| 大兴区| 全椒县| 太谷县| 松桃| 江山市| 清镇市| 金昌市| 沁水县| 丰原市| 门头沟区| 湟源县| 晋中市|