最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談C#跨線(xiàn)程調(diào)用窗體控件(比如TextBox)引發(fā)的線(xiàn)程安全問(wèn)題

 更新時(shí)間:2017年11月22日 10:12:23   作者:絳河  
下面小編就為大家分享一篇淺談C#跨線(xiàn)程調(diào)用窗體控件(比如TextBox)引發(fā)的線(xiàn)程安全問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助

如何:對(duì) Windows 窗體控件進(jìn)行線(xiàn)程安全調(diào)用

訪問(wèn) Windows 窗體控件本質(zhì)上不是線(xiàn)程安全的。 如果有兩個(gè)或多個(gè)線(xiàn)程操作某一控件的狀態(tài),則可能會(huì)迫使該控件進(jìn)入一種不一致的狀態(tài)。 還可能會(huì)出現(xiàn)其他與線(xiàn)程相關(guān)的 Bug,例如爭(zhēng)用情況和死鎖。 確保以線(xiàn)程安全方式訪問(wèn)控件非常重要。

在未使用 Invoke 方法的情況下,從不是創(chuàng)建某個(gè)控件的線(xiàn)程的其他線(xiàn)程調(diào)用該控件是不安全的。 以下非線(xiàn)程安全的調(diào)用的示例。

// 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 可幫助您檢測(cè)以非線(xiàn)程安全方式訪問(wèn)控件這一問(wèn)題。 在調(diào)試器中運(yùn)行應(yīng)用程序時(shí),如果一個(gè)不是創(chuàng)建某個(gè)控件的線(xiàn)程的其他線(xiàn)程調(diào)用該控件,則調(diào)試器會(huì)引發(fā)一個(gè) InvalidOperationException,并顯示以下消息:“從不是創(chuàng)建控件控件名稱(chēng) 的線(xiàn)程訪問(wèn)它?!?/p>

此異常在調(diào)試期間和運(yùn)行時(shí)的某些情況下可靠地發(fā)生。 在調(diào)試以 .NET Framework 2.0 版之前的 .NET Framework 編寫(xiě)的應(yīng)用程序時(shí),可能會(huì)出現(xiàn)此異常。 我們強(qiáng)烈建議您在發(fā)現(xiàn)此問(wèn)題時(shí)進(jìn)行修復(fù),但您可以通過(guò)將 CheckForIllegalCrossThreadCalls 屬性設(shè)置為 false 來(lái)禁用它。(不推薦)

對(duì) Windows 窗體控件進(jìn)行線(xiàn)程安全調(diào)用

查詢(xún)控件的 InvokeRequired 屬性。

如果 InvokeRequired 返回 true,則使用實(shí)際調(diào)用控件的委托來(lái)調(diào)用 Invoke。

如果 InvokeRequired 返回 false,則直接調(diào)用控件。

在下面的代碼示例中,將在由后臺(tái)線(xiàn)程執(zhí)行的 ThreadProcSafe 方法中實(shí)現(xiàn)線(xiàn)程安全調(diào)用。 如果 TextBox 控件的 InvokeRequired 返回 true,則 ThreadProcSafe 方法會(huì)創(chuàng)建 SetTextCallback 的一個(gè)實(shí)例,并將該實(shí)例傳遞給窗體的 Invoke 方法。 這使得 SetText 方法被創(chuàng)建 TextBox 控件的線(xiàn)程調(diào)用,而且在此線(xiàn)程上下文中將直接設(shè)置 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#跨線(xiàn)程調(diào)用窗體控件(比如TextBox)引發(fā)的線(xiàn)程安全問(wèn)題就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

昭苏县| 友谊县| 莲花县| 白沙| 尼木县| 昔阳县| 梁山县| 汶上县| 绥中县| 安达市| 宁化县| 深圳市| 浦城县| 土默特左旗| 涪陵区| 卓尼县| 天水市| 日喀则市| 景洪市| 四川省| 尼玛县| 鄱阳县| 保亭| 英德市| 舒城县| 遂宁市| 杭锦旗| 乐亭县| 寻乌县| 新竹县| 宜宾县| 驻马店市| 霞浦县| 康定县| 明水县| 浦北县| 濮阳县| 通渭县| 稷山县| 通河县| 九龙坡区|