版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、使用多線程提高 Windows 窗體應(yīng)用程序的性能時(shí),必須注意以線程安全方式調(diào)用控件。示例訪問(wèn) Windows 窗體控件本質(zhì)上不是線程安全的。如果有兩個(gè)或多個(gè)線程操作某一控件的狀態(tài),則可能會(huì)迫使該控件進(jìn)入一種不一致的狀態(tài)。還可能出現(xiàn)其他與線程相關(guān)的 bug,包括爭(zhēng)用情況和死鎖。確保以線程安全方式訪問(wèn)控件非常重要。.NET Framework 有助于在以非線程安全方式訪問(wèn)控件時(shí)檢測(cè)到這一問(wèn)題。在調(diào)試器中運(yùn)行應(yīng)用程序時(shí),如果創(chuàng)建某控件的線程之外的其他線程試圖調(diào)用該控件,則調(diào)試器會(huì)引發(fā)一個(gè) InvalidOperationException,并顯示以下消息:“從不是創(chuàng)建控件控件名稱 的線程訪問(wèn)它。”
2、 此異常在調(diào)試期間和運(yùn)行時(shí)的某些情況下可靠地發(fā)生。強(qiáng)烈建議您在顯示此錯(cuò)誤信息時(shí)修復(fù)此問(wèn)題。在調(diào)試以 .NET Framework 2.0 版之前的 .NET Framework 編寫的應(yīng)用程序時(shí),可能會(huì)出現(xiàn)此異常。注意:可以通過(guò)將 CheckForIllegalCrossThreadCalls 屬性的值設(shè)置為 false 來(lái)禁用此異常。這會(huì)使控件以與在 Visual Studio 2003 下相同的方式運(yùn)行。下面的代碼示例演示如何從輔助線程以線程安全方式和非線程安全方式調(diào)用 Windows 窗體控件。它演示一種以非線程安全方式設(shè)置 TextBox 控件的 Text 屬性的方法,還演示兩種以線程
3、安全方式設(shè)置 Text 屬性的方法。Visual Basic 復(fù)制代碼Imports SystemImports System.ComponentModelImports System.ThreadingImports System.Windows.FormsPublic Class Form1Inherits Form' This delegate enables asynchronous calls for setting' the text property on a TextBox control.Delegate Sub SetTextCallback(te
4、xt As String' This thread is used to demonstrate both thread-safe and' unsafe ways to call a Windows Forms control.Private demoThread As Thread = Nothing' This BackgroundWorker is used to demonstrate the ' preferred way of performing asynchronous operations.Private WithEvents backgro
5、undWorker1 As BackgroundWorkerPrivate textBox1 As TextBoxPrivate WithEvents setTextUnsafeBtn As ButtonPrivate WithEvents setTextSafeBtn As ButtonPrivate WithEvents setTextBackgroundWorkerBtn As ButtonPrivate components As System.ComponentModel.IContainer = NothingPublic Sub New(InitializeComponent(E
6、nd SubProtected Overrides Sub Dispose(disposing As BooleanIf disposing AndAlso (components IsNot Nothing Thencomponents.Dispose(End IfMyBase.Dispose(disposingEnd Sub' This event handler creates a thread that calls a ' Windows Forms control in an unsafe way.Private Sub setTextUnsafeBtn_Click(
7、 _ByVal sender As Object, _ByVal e As EventArgs Handles setTextUnsafeBtn.ClickMe.demoThread = New Thread( _New ThreadStart(AddressOf Me.ThreadProcUnsafeMe.demoThread.Start(End Sub' This method is executed on the worker thread and makes' an unsafe call on the TextBox control.Private Sub Threa
8、dProcUnsafe(Me.textBox1.Text = "This text was set unsafely."End Sub ' This event handler creates a thread that calls a ' Windows Forms control in a thread-safe way.Private Sub setTextSafeBtn_Click( _ByVal sender As Object, _ByVal e As EventArgs Handles setTextSafeBtn.ClickMe.demoTh
9、read = New Thread( _New ThreadStart(AddressOf Me.ThreadProcSafeMe.demoThread.Start(End Sub' This method is executed on the worker thread and makes' a thread-safe call on the TextBox control.Private Sub ThreadProcSafe(Me.SetText("This text was set safely."End Sub' This method de
10、monstrates a pattern for making thread-safe' calls on a Windows Forms control. '' If the calling thread is different from the thread that' created the TextBox control, this method creates a' SetTextCallback and calls itself asynchronously using the' Invoke method.'' I
11、f the calling thread is the same as the thread that created' the TextBox control, the Text property is set directly. Private Sub SetText(ByVal text As String' InvokeRequired required compares the thread ID of the' calling thread to the thread ID of the creating thread.' If these thre
12、ads are different, it returns true.If Me.textBox1.InvokeRequired ThenDim d As New SetTextCallback(AddressOf SetTextMe.Invoke(d, New Object( textElseMe.textBox1.Text = textEnd IfEnd Sub' This event handler starts the form's ' BackgroundWorker by calling RunWorkerAsync.'' The Text
13、property of the TextBox control is set' when the BackgroundWorker raises the RunWorkerCompleted' event.Private Sub setTextBackgroundWorkerBtn_Click( _ByVal sender As Object, _ByVal e As EventArgs Handles setTextBackgroundWorkerBtn.ClickMe.backgroundWorker1.RunWorkerAsync(End Sub' This ev
14、ent handler sets the Text property of the TextBox' control. It is called on the thread that created the ' TextBox control, so the call is thread-safe.'' BackgroundWorker is the preferred way to perform asynchronous' operations.Private Sub backgroundWorker1_RunWorkerCompleted( _By
15、Val sender As Object, _ByVal e As RunWorkerCompletedEventArgs _Handles backgroundWorker1.RunWorkerCompletedMe.textBox1.Text = _"This text was set safely by BackgroundWorker."End Sub#Region "Windows Form Designer generated code"Private Sub InitializeComponent(Me.textBox1 = New Sys
16、tem.Windows.Forms.TextBox(Me.setTextUnsafeBtn = New System.Windows.Forms.Button(Me.setTextSafeBtn = New System.Windows.Forms.Button(Me.setTextBackgroundWorkerBtn = New System.Windows.Forms.Button(Me.backgroundWorker1 = New System.ComponentModel.BackgroundWorker(Me.SuspendLayout(' ' textBox1&
17、#39; Me.textBox1.Location = New System.Drawing.Point(12, 12Me.textBox1.Name = "textBox1"Me.textBox1.Size = New System.Drawing.Size(240, 20Me.textBox1.TabIndex = 0' ' setTextUnsafeBtn' Me.setTextUnsafeBtn.Location = New System.Drawing.Point(15, 55Me.setTextUnsafeBtn.Name = "
18、;setTextUnsafeBtn"Me.setTextUnsafeBtn.TabIndex = 1Me.setTextUnsafeBtn.Text = "Unsafe Call"' ' setTextSafeBtn' Me.setTextSafeBtn.Location = New System.Drawing.Point(96, 55Me.setTextSafeBtn.Name = "setTextSafeBtn"Me.setTextSafeBtn.TabIndex = 2Me.setTextSafeBtn.Text
19、 = "Safe Call"' ' setTextBackgroundWorkerBtn' Me.setTextBackgroundWorkerBtn.Location = New System.Drawing.Point(177, 55Me.setTextBackgroundWorkerBtn.Name = "setTextBackgroundWorkerBtn"Me.setTextBackgroundWorkerBtn.TabIndex = 3Me.setTextBackgroundWorkerBtn.Text = "
20、;Safe BW Call"' ' backgroundWorker1' ' ' Form1' Me.ClientSize = New System.Drawing.Size(268, 96Me.Controls.Add(setTextBackgroundWorkerBtnMe.Controls.Add(setTextSafeBtnMe.Controls.Add(setTextUnsafeBtnMe.Controls.Add(textBox1Me.Name = "Form1"Me.Text = "Form1
21、"Me.ResumeLayout(FalseMe.PerformLayout(End Sub 'InitializeComponent #End Region_ Shared Sub Main(Application.EnableVisualStyles(Application.Run(New Form1(End SubEnd ClassC# 復(fù)制代碼using System;using System.ComponentModel;using System.Threading;using System.Windows.Forms;namespace CrossThr
22、eadDemopublic class Form1 : Form/ This delegate enables asynchronous calls for setting/ the text property on a TextBox control.delegate void SetTextCallback(string text;/ This thread is used to demonstrate both thread-safe and/ unsafe ways to call a Windows Forms control.private Thread demoThread =
23、null;/ This BackgroundWorker is used to demonstrate the / preferred way of performing asynchronous operations.private BackgroundWorker backgroundWorker1;private TextBox textBox1;private Button setTextUnsafeBtn;private Button setTextSafeBtn;private Button setTextBackgroundWorkerBtn;private System.Com
24、ponentModel.IContainer components = null;public Form1(InitializeComponent(;protected override void Dispose(bool disposingif (disposing && (components != nullcomponents.Dispose(;base.Dispose(disposing;/ This event handler creates a thread that calls a / Windows Forms control in an unsafe way.
25、private void setTextUnsafeBtn_Click(object sender, EventArgs ethis.demoThread = new Thread(new ThreadStart(this.ThreadProcUnsafe;this.demoThread.Start(;/ This method is executed on the worker thread and makes/ an unsafe call on the TextBox control.private void ThreadProcUnsafe(this.textBox1.Text = &
26、quot;This text was set unsafely."/ This event handler creates a thread that calls a / Windows Forms control in a thread-safe way.private void setTextSafeBtn_Click(object sender, EventArgs ethis.demoThread = new Thread(new ThreadStart(this.ThreadProcSafe;this.demoThread.Start(;/ This method is e
27、xecuted on the worker thread and makes/ a thread-safe call on the TextBox control.private void ThreadProcSafe(this.SetText("This text was set safely."/ This method demonstrates a pattern for making thread-safe/ calls on a Windows Forms control. / If the calling thread is different from the
28、 thread that/ created the TextBox control, this method creates a/ SetTextCallback and calls itself asynchronously using the/ Invoke method./ If the calling thread is the same as the thread that created/ the TextBox control, the Text property is set directly. private void SetText(string text/ InvokeR
29、equired required compares the thread ID of the/ calling thread to the thread ID of the creating thread./ If these threads are different, it returns true.if (this.textBox1.InvokeRequired SetTextCallback d = new SetTextCallback(SetText;this.Invoke(d, new object text ;elsethis.textBox1.Text = text;/ Th
30、is event handler starts the form's / BackgroundWorker by calling RunWorkerAsync./ The Text property of the TextBox control is set/ when the BackgroundWorker raises the RunWorkerCompleted/ event.private void setTextBackgroundWorkerBtn_Click(object sender, EventArgs ethis.backgroundWorker1.RunWork
31、erAsync(;/ This event handler sets the Text property of the TextBox/ control. It is called on the thread that created the / TextBox control, so the call is thread-safe./ BackgroundWorker is the preferred way to perform asynchronous/ operations.private void backgroundWorker1_RunWorkerCompleted(object
32、 sender, RunWorkerCompletedEventArgs ethis.textBox1.Text = "This text was set safely by BackgroundWorker."#region Windows Form Designer generated codeprivate void InitializeComponent(this.textBox1 = new System.Windows.Forms.TextBox(;this.setTextUnsafeBtn = new System.Windows.Forms.Button(;
33、this.setTextSafeBtn = new System.Windows.Forms.Button(;this.setTextBackgroundWorkerBtn = new System.Windows.Forms.Button(;this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(;this.SuspendLayout(;/ / textBox1/ this.textBox1.Location = new System.Drawing.Point(12, 12;this.textBox1.Name
34、 = "textBox1"this.textBox1.Size = new System.Drawing.Size(240, 20;this.textBox1.TabIndex = 0;/ / setTextUnsafeBtn/ this.setTextUnsafeBtn.Location = new System.Drawing.Point(15, 55;this.setTextUnsafeBtn.Name = "setTextUnsafeBtn"this.setTextUnsafeBtn.TabIndex = 1;this.setTextUnsafe
35、Btn.Text = "Unsafe Call"this.setTextUnsafeBtn.Click += new System.EventHandler(this.setTextUnsafeBtn_Click;/ / setTextSafeBtn/ this.setTextSafeBtn.Location = new System.Drawing.Point(96, 55;this.setTextSafeBtn.Name = "setTextSafeBtn"this.setTextSafeBtn.TabIndex = 2;this.setTextSa
36、feBtn.Text = "Safe Call"this.setTextSafeBtn.Click += new System.EventHandler(this.setTextSafeBtn_Click;/ / setTextBackgroundWorkerBtn/ this.setTextBackgroundWorkerBtn.Location = new System.Drawing.Point(177, 55;this.setTextBackgroundWorkerBtn.Name = "setTextBackgroundWorkerBtn"th
37、is.setTextBackgroundWorkerBtn.TabIndex = 3;this.setTextBackgroundWorkerBtn.Text = "Safe BW Call"this.setTextBackgroundWorkerBtn.Click += new System.EventHandler(this.setTextBackgroundWorkerBtn_Click;/ / backgroundWorker1/ this.backgroundWorker1.RunWorkerCompleted += new System.ComponentMod
38、el.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted;/ / Form1/ this.ClientSize = new System.Drawing.Size(268, 96;this.Controls.Add(this.setTextBackgroundWorkerBtn;this.Controls.Add(this.setTextSafeBtn;this.Controls.Add(this.setTextUnsafeBtn;this.Controls.Add(this.textBox1;thi
39、s.Name = "Form1"this.Text = "Form1"this.ResumeLayout(false;this.PerformLayout(;#endregionSTAThreadstatic void Main(Application.EnableVisualStyles(;Application.Run(new Form1(;對(duì) Windows 窗體控件的非線程安全調(diào)用對(duì) Windows 窗體控件的非線程安全調(diào)用方式是從輔助線程直接調(diào)用。調(diào)用應(yīng)用程序時(shí),調(diào)試器會(huì)引發(fā)一個(gè) InvalidOperationException,警告對(duì)控件的
40、調(diào)用不是線程安全的。Visual Basic 復(fù)制代碼' This event handler creates a thread that calls a ' Windows Forms control in an unsafe way.Private Sub setTextUnsafeBtn_Click( _ByVal sender As Object, _ByVal e As EventArgs Handles setTextUnsafeBtn.ClickMe.demoThread = New Thread( _New ThreadStart(AddressOf
41、Me.ThreadProcUnsafeMe.demoThread.Start(End Sub' This method is executed on the worker thread and makes' an unsafe call on the TextBox control.Private Sub ThreadProcUnsafe(Me.textBox1.Text = "This text was set unsafely."End Sub C# 復(fù)制代碼/ This event handler creates a thread that
42、calls a / Windows Forms control in an unsafe way.private void setTextUnsafeBtn_Click(object sender, EventArgs ethis.demoThread = new Thread(new ThreadStart(this.ThreadProcUnsafe;this.demoThread.Start(;/ This method is executed on the worker thread and makes/ an unsafe call on the TextBox control.pri
43、vate void ThreadProcUnsafe(this.textBox1.Text = "This text was set unsafely."對(duì) Windows 窗體控件的線程安全調(diào)用對(duì) Windows 窗體控件進(jìn)行線程安全調(diào)用1. 查詢控件的 InvokeRequired 屬性。2. 如果 InvokeRequired 返回 true,則使用實(shí)際調(diào)用控件的委托來(lái)調(diào)用 Invoke。3. 如果 InvokeRequired 返回 false,則直接調(diào)用控件。在下面的代碼示例中,此邏輯是在一個(gè)稱為 SetText 的實(shí)用工具方法中實(shí)現(xiàn)的。名為 SetTextDel
44、egate 的委托類型封裝 SetText 方法。TextBox 控件的 InvokeRequired 返回 true 時(shí),SetText 方法創(chuàng)建 SetTextDelegate 的一個(gè)實(shí)例,并調(diào)用窗體的 Invoke 方法。這使得 SetText 方法被創(chuàng)建 TextBox 控件的線程調(diào)用,而且在此線程上下文中將直接設(shè)置 Text 屬性。Visual Basic 復(fù)制代碼' This event handler creates a thread that calls a ' Windows Forms control in a thread-safe way.Pr
45、ivate Sub setTextSafeBtn_Click( _ByVal sender As Object, _ByVal e As EventArgs Handles setTextSafeBtn.ClickMe.demoThread = New Thread( _New ThreadStart(AddressOf Me.ThreadProcSafeMe.demoThread.Start(End Sub' This method is executed on the worker thread and makes' a thread-safe call on the Te
46、xtBox control.Private Sub ThreadProcSafe(Me.SetText("This text was set safely."End SubC# 復(fù)制代碼p / This event handler creates a thread that calls a / Windows Forms control in a thread-safe way.private void setTextSafeBtn_Click(object sender, EventArgs ethis.demoThread = new Thread(new T
47、hreadStart(this.ThreadProcSafe;this.demoThread.Start(;/ This method is executed on the worker thread and makes/ a thread-safe call on the TextBox control.private void ThreadProcSafe(this.SetText("This text was set safely."p Visual Basic 復(fù)制代碼p ' This method demonstrates a pattern f
48、or making thread-safe' calls on a Windows Forms control. '' If the calling thread is different from the thread that' created the TextBox control, this method creates a' SetTextCallback and calls itself asynchronously using the' Invoke method.'' If the calling thread i
49、s the same as the thread that created' the TextBox control, the Text property is set directly. Private Sub SetText(ByVal text As String' InvokeRequired required compares the thread ID of the' calling thread to the thread ID of the creating thread.' If these threads are different, it
50、returns true.If Me.textBox1.InvokeRequired ThenDim d As New SetTextCallback(AddressOf SetTextMe.Invoke(d, New Object( textElseMe.textBox1.Text = textEnd IfEnd SubC# 復(fù)制代碼/ This method demonstrates a pattern for making thread-safe/ calls on a Windows Forms control. / If the calling thread is diff
51、erent from the thread that/ created the TextBox control, this method creates a/ SetTextCallback and calls itself asynchronously using the/ Invoke method./ If the calling thread is the same as the thread that created/ the TextBox control, the Text property is set directly. private void SetText(string
52、 text/ InvokeRequired required compares the thread ID of the/ calling thread to the thread ID of the creating thread./ If these threads are different, it returns true.if (this.textBox1.InvokeRequired SetTextCallback d = new SetTextCallback(SetText;this.Invoke(d, new object text ;elsethis.textBox1.Te
53、xt = text;使用 BackgroundWorker 進(jìn)行的線程安全調(diào)用在應(yīng)用程序中實(shí)現(xiàn)多線程的首選方式是使用 BackgroundWorker 組件。BackgroundWorker 組件使用事件驅(qū)動(dòng)模型實(shí)現(xiàn)多線程。輔助線程運(yùn)行 DoWork 事件處理程序,創(chuàng)建控件的線程運(yùn)行 ProgressChanged 和 RunWorkerCompleted 事件處理程序。注意不要從 DoWork 事件處理程序調(diào)用您的任何控件。下面的代碼示例不異步執(zhí)行任何工作,因此沒有 DoWork 事件處理程序的實(shí)現(xiàn)。TextBox 控件的 Text 屬性在 RunWorkerCompleted 事件處理程序
54、中直接設(shè)置。Visual Basic 復(fù)制代碼' This event handler starts the form's ' BackgroundWorker by calling RunWorkerAsync.'' The Text property of the TextBox control is set' when the BackgroundWorker raises the RunWorkerCompleted' event.Private Sub setTextBackgroundWorkerBtn_Click( _ByVal sender As Obj
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 攪拌站施工合同合作條件3篇
- 教育機(jī)構(gòu)學(xué)員交費(fèi)合同3篇
- 教育機(jī)構(gòu)課程顧問(wèn)助理工作合同3篇
- 安徽軟件行業(yè)程序員勞動(dòng)合同范本3篇
- 捷克語(yǔ)教師簡(jiǎn)易勞動(dòng)合同3篇
- 教育圖書銷售合同
- 房屋買賣合同的撰寫要點(diǎn)3篇
- 撤訴授權(quán)書格式樣本3篇
- 擋水墻工程建筑合同范例3篇
- 提高員工滿意度方案3篇
- 醫(yī)藥行業(yè)合規(guī)培訓(xùn)
- 2024年低壓電工資格考試必考題庫(kù)及答案(共400題)
- 【MOOC】公司金融-江西財(cái)經(jīng)大學(xué) 中國(guó)大學(xué)慕課MOOC答案
- 世界衛(wèi)生組織人類精液及精子-宮頸粘液相互作用實(shí)驗(yàn)室檢驗(yàn)手冊(cè)第五版
- 殯儀館鮮花采購(gòu)?fù)稑?biāo)方案(技術(shù)方案)
- 消化道大出血應(yīng)急預(yù)案演練
- 光伏項(xiàng)目達(dá)標(biāo)投產(chǎn)實(shí)施細(xì)則-施工
- 中國(guó)的世界文化遺產(chǎn)-英文版
- 系統(tǒng)集成售前技術(shù)年終總結(jié)
- 微信公眾號(hào)運(yùn)營(yíng)合同三篇
- 《網(wǎng)絡(luò)營(yíng)銷》試題及答案2
評(píng)論
0/150
提交評(píng)論