c#-跨執行緒控制元件訪問問題

iDotNetSpace發表於2009-01-16

新手最近遇到這樣的問題: a執行緒去訪問b執行緒的控制元件,編譯器報錯。在網上找了一下解決方案,和大家分享下。

解決方法有3:
1, 不安全的方法: Control.CheckForIllegalCrossThreadCalls 設定為false (.net1.0中沒有)
2,
安全的方法: 非同步委託
3,
安全的方法: 就是使用BackgroundWorker來替代你自己建立的執行緒(.net1.0中沒有)

主要說下第二種方法,例項程式碼:

 

c#-跨執行緒控制元件訪問問題
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt 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.";
         }
         
          Windows Form Designer generated code
         
         
         [STAThread]
         
static void Main()
          {
             Application.EnableVisualStyles();
             Application.Run(
new Form1());
         }
         
     }
 }

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-539841/,如需轉載,請註明出處,否則將追究法律責任。

相關文章