亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

淺談C#跨線程調用窗體控件(比如TextBox)引發的線程安全問題

2019-10-29 21:07:21
字體:
來源:轉載
供稿:網友

如何:對 Windows 窗體控件進行線程安全調用

訪問 Windows 窗體控件本質上不是線程安全的。 如果有兩個或多個線程操作某一控件的狀態,則可能會迫使該控件進入一種不一致的狀態。 還可能會出現其他與線程相關的 Bug,例如爭用情況和死鎖。 確保以線程安全方式訪問控件非常重要。

在未使用 Invoke 方法的情況下,從不是創建某個控件的線程的其他線程調用該控件是不安全的。 以下非線程安全的調用的示例。

// This event handler creates a thread that calls a   // Windows Forms control in an unsafe way.  private void setTextUnsafeBtn_Click(   object sender,    EventArgs e)  {   this.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 = "This text was set unsafely.";  }

.NET Framework 可幫助您檢測以非線程安全方式訪問控件這一問題。 在調試器中運行應用程序時,如果一個不是創建某個控件的線程的其他線程調用該控件,則調試器會引發一個 InvalidOperationException,并顯示以下消息:“從不是創建控件控件名稱 的線程訪問它。”

此異常在調試期間和運行時的某些情況下可靠地發生。 在調試以 .NET Framework 2.0 版之前的 .NET Framework 編寫的應用程序時,可能會出現此異常。 我們強烈建議您在發現此問題時進行修復,但您可以通過將 CheckForIllegalCrossThreadCalls 屬性設置為 false 來禁用它。(不推薦)

對 Windows 窗體控件進行線程安全調用

查詢控件的 InvokeRequired 屬性。

如果 InvokeRequired 返回 true,則使用實際調用控件的委托來調用 Invoke。

如果 InvokeRequired 返回 false,則直接調用控件。

在下面的代碼示例中,將在由后臺線程執行的 ThreadProcSafe 方法中實現線程安全調用。 如果 TextBox 控件的 InvokeRequired 返回 true,則 ThreadProcSafe 方法會創建 SetTextCallback 的一個實例,并將該實例傳遞給窗體的 Invoke 方法。 這使得 SetText 方法被創建 TextBox 控件的線程調用,而且在此線程上下文中將直接設置 Text 屬性。

// This event handler creates a thread that calls a   // Windows Forms control in a thread-safe way.  private void setTextSafeBtn_Click(   object sender,    EventArgs e)  {    this.demoThread =     new Thread(new ThreadStart(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.");  }
using System;using System.ComponentModel;using System.Threading;using System.Windows.Forms;namespace CrossThreadDemo{ public 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 = 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.ComponentModel.IContainer components = null;  public Form1()  {   InitializeComponent();  }  protected override void Dispose(bool disposing)  {   if (disposing && (components != null))   {    components.Dispose();   }   base.Dispose(disposing);  }  // This event handler creates a thread that calls a   // Windows Forms control in an unsafe way.  private void setTextUnsafeBtn_Click(   object sender,    EventArgs e)  {   this.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 = "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 e)  {   this.demoThread =     new Thread(new ThreadStart(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.");  }  // This method demonstrates 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.  //  // 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)  {   // 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 });   }   else   {    this.textBox1.Text = text;   }  }  // 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 void setTextBackgroundWorkerBtn_Click(   object sender,    EventArgs e)  {   this.backgroundWorker1.RunWorkerAsync();  }    // 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 sender,    RunWorkerCompletedEventArgs e)  {   this.textBox1.Text =     "This text was set safely by BackgroundWorker.";  }  #region Windows Form Designer generated code  private void InitializeComponent()  {   this.textBox1 = new System.Windows.Forms.TextBox();   this.setTextUnsafeBtn = new System.Windows.Forms.Button();   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 = "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.setTextUnsafeBtn.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.setTextSafeBtn.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";   this.setTextBackgroundWorkerBtn.TabIndex = 3;   this.setTextBackgroundWorkerBtn.Text = "Safe BW Call";   this.setTextBackgroundWorkerBtn.Click += new System.EventHandler(this.setTextBackgroundWorkerBtn_Click);   //    // backgroundWorker1   //    this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.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);   this.Name = "Form1";   this.Text = "Form1";   this.ResumeLayout(false);   this.PerformLayout();  }  #endregion  [STAThread]  static void Main()  {   Application.EnableVisualStyles();   Application.Run(new Form1());  } }}

以上這篇淺談C#跨線程調用窗體控件(比如TextBox)引發的線程安全問題就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到c#教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品久久久久不卡| 精品久久久在线观看| 亚洲欧美色图片| 久久夜色撩人精品| 欧美亚洲在线播放| 91精品视频播放| 亚洲欧美日韩第一区| 国内精品视频在线| 亚洲欧美日韩在线高清直播| 国产一区香蕉久久| 欧美日韩国产一区二区三区| 日本高清不卡的在线| 国产精品欧美一区二区| 国产精品无av码在线观看| 国产噜噜噜噜噜久久久久久久久| 欧美性生交大片免费| 久久国产一区二区三区| 国产www精品| 亚洲一区美女视频在线观看免费| 亚洲人精品午夜在线观看| 久久手机免费视频| 亚洲的天堂在线中文字幕| 最近中文字幕日韩精品| 欧美国产精品人人做人人爱| 亚洲www在线| 韩曰欧美视频免费观看| 成人av资源在线播放| 欧美三级免费观看| 午夜精品久久久久久久99热浪潮| 中文字幕欧美视频在线| 55夜色66夜色国产精品视频| 午夜免费日韩视频| 日韩在线观看成人| 中文字幕亚洲欧美一区二区三区| 亚洲精品中文字幕av| 国产精品av网站| 日韩欧美高清视频| 国产一区欧美二区三区| 国内精品美女av在线播放| 欧美性生活大片免费观看网址| 日本久久亚洲电影| 国产精品aaa| 国产小视频国产精品| 欧美成人亚洲成人日韩成人| 日韩欧美国产免费播放| 欧美中文在线免费| 成人国产精品久久久| 亚洲精品xxxx| 亚洲另类欧美自拍| 91精品国产91久久久久久不卡| 亚洲午夜国产成人av电影男同| 亚洲欧洲视频在线| 在线成人激情黄色| 91国偷自产一区二区三区的观看方式| 国产精品久久久久久久久免费| 久久夜色精品国产欧美乱| 亚洲国产精品推荐| 亚洲美女视频网| 午夜精品久久久久久久男人的天堂| 久久久久九九九九| 欧美一级成年大片在线观看| 久热精品视频在线观看一区| 久久亚洲精品一区二区| 日韩影视在线观看| 大胆人体色综合| 这里只有视频精品| 亚洲少妇激情视频| 国产一区二区三区视频| 国产精品wwwwww| 亚洲一区亚洲二区| 亚洲精品国产精品自产a区红杏吧| 欧美精品免费看| 日韩国产中文字幕| 精品国产一区av| 97精品国产aⅴ7777| 欧美在线视频一区| 另类少妇人与禽zozz0性伦| 亚洲精品电影在线观看| 欧美高清自拍一区| 国产日韩欧美在线播放| 亚洲第一色中文字幕| 在线视频一区二区| 欧美性xxxxx极品娇小| 欧美高清视频一区二区| 日韩中文字幕视频| 91久热免费在线视频| 久久久久久噜噜噜久久久精品| 国产美女精品视频| 国产精品免费久久久久久| 成人在线播放av| 91精品视频在线| 日本高清视频一区| 5278欧美一区二区三区| 亚洲xxx大片| 成人免费自拍视频| 亚州av一区二区| 亚洲一区二区中文字幕| 理论片在线不卡免费观看| 日韩经典第一页| 欧美成人精品一区| 欧美日韩中文字幕在线| 欧美一区二区三区精品电影| 日韩欧美在线视频观看| 亚洲大胆人体av| 亚洲最大福利视频网| 国产精品视频色| 亚洲香蕉伊综合在人在线视看| 91九色视频导航| 97av视频在线| 亚洲奶大毛多的老太婆| 成人妇女免费播放久久久| 国产精品96久久久久久又黄又硬| 国产99在线|中文| 欧美高清视频一区二区| 欧美国产日韩中文字幕在线| 欧美丰满少妇xxxxx| 在线观看国产精品日韩av| 欧美成人午夜免费视在线看片| 97精品久久久中文字幕免费| 国产99久久精品一区二区 夜夜躁日日躁| 九九精品在线播放| 隔壁老王国产在线精品| 国产一区二区丝袜| 奇米一区二区三区四区久久| 亚洲精品乱码久久久久久按摩观| 最近中文字幕mv在线一区二区三区四区| 亚洲最大福利视频| 久久亚洲国产精品成人av秋霞| 日韩精品极品毛片系列视频| 91在线精品视频| 亚洲人成人99网站| 久久综合五月天| 日韩专区中文字幕| 92国产精品久久久久首页| 色综合老司机第九色激情| 欧美激情亚洲视频| 亚洲精品一区中文字幕乱码| 亚洲一区二区三区视频| 欧美日韩激情小视频| 亚洲午夜久久久影院| 欧美日韩国产页| 在线播放国产一区中文字幕剧情欧美| 国产免费一区二区三区香蕉精| 久久久久中文字幕2018| 91精品国产777在线观看| 久久久久久久影视| 久久精品视频在线观看| 国模精品一区二区三区色天香| 97超碰国产精品女人人人爽| 国产欧美久久一区二区| 亚洲精品午夜精品| 91情侣偷在线精品国产| 成人免费观看网址| 国产日韩欧美成人| 亚洲女人被黑人巨大进入| 欧美午夜精品久久久久久人妖| 欧美成aaa人片在线观看蜜臀| 久久免费福利视频| 欧美一区二区三区免费视| 欧美激情小视频| 欧美激情久久久久| 欧美日韩福利在线观看| 国产精品视频最多的网站| 久久久国产视频|