如何:對(duì)Windows窗體控件進(jìn)行線程安全調(diào)用_第1頁(yè)
如何:對(duì)Windows窗體控件進(jìn)行線程安全調(diào)用_第2頁(yè)
如何:對(duì)Windows窗體控件進(jìn)行線程安全調(diào)用_第3頁(yè)
如何:對(duì)Windows窗體控件進(jìn)行線程安全調(diào)用_第4頁(yè)
如何:對(duì)Windows窗體控件進(jìn)行線程安全調(diào)用_第5頁(yè)
已閱讀5頁(yè),還剩22頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論