跨线程的控件访问

新手经常会遇到这样的问题: a线程去访问b线程的控件,编译器报错(.net1.0编译时好像不会报,.net2.0是肯定会的).

解决方法有3种:
1, 不安全的方法: 将 Control.CheckForIllegalCrossThreadCalls 设置为false (.net1.0中没有)
2,安全的方法: 异步委托
3, 安全的方法: 就是使用BackgroundWorker来替代你自己创建的线程(.net1.0中没有)

以下是示例代码

<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->usingSystem;
usingSystem.ComponentModel;
usingSystem.Threading;
usingSystem.Windows.Forms;

namespaceCrossThreadDemo
{
publicclassForm1:Form
{
//Thisdelegateenablesasynchronouscallsforsetting
//thetextpropertyonaTextBoxcontrol.
delegatevoidSetTextCallback(stringtext);

//Thisthreadisusedtodemonstrateboththread-safeand
//unsafewaystocallaWindowsFormscontrol.
privateThreaddemoThread=null;

//ThisBackgroundWorkerisusedtodemonstratethe
//preferredwayofperformingasynchronousoperations.
privateBackgroundWorkerbackgroundWorker1;

privateTextBoxtextBox1;
privateButtonsetTextUnsafeBtn;
privateButtonsetTextSafeBtn;
privateButtonsetTextBackgroundWorkerBtn;

privateSystem.ComponentModel.IContainercomponents=null;

publicForm1()
{
InitializeComponent();
}


protectedoverridevoidDispose(booldisposing)
{
if(disposing&&(components!=null))
{
components.Dispose();
}

base.Dispose(disposing);
}


//Thiseventhandlercreatesathreadthatcallsa
//WindowsFormscontrolinanunsafeway.
privatevoidsetTextUnsafeBtn_Click(
objectsender,
EventArgse)
{
this.demoThread=
newThread(newThreadStart(this.ThreadProcUnsafe));

this.demoThread.Start();
}


//Thismethodisexecutedontheworkerthreadandmakes
//anunsafecallontheTextBoxcontrol.
privatevoidThreadProcUnsafe()
{
this.textBox1.Text="Thistextwassetunsafely.";
}


//Thiseventhandlercreatesathreadthatcallsa
//WindowsFormscontrolinathread-safeway.
privatevoidsetTextSafeBtn_Click(
objectsender,
EventArgse)
{
this.demoThread=
newThread(newThreadStart(this.ThreadProcSafe));

this.demoThread.Start();
}


//Thismethodisexecutedontheworkerthreadandmakes
//athread-safecallontheTextBoxcontrol.
privatevoidThreadProcSafe()
{
this.SetText("Thistextwassetsafely.");
}


//Thismethoddemonstratesapatternformakingthread-safe
//callsonaWindowsFormscontrol.
//
//Ifthecallingthreadisdifferentfromthethreadthat
//createdtheTextBoxcontrol,thismethodcreatesa
//SetTextCallbackandcallsitselfasynchronouslyusingthe
//Invokemethod.
//
//Ifthecallingthreadisthesameasthethreadthatcreated
//theTextBoxcontrol,theTextpropertyissetdirectly.

privatevoidSetText(stringtext)
{
//InvokeRequiredrequiredcomparesthethreadIDofthe
//callingthreadtothethreadIDofthecreatingthread.
//Ifthesethreadsaredifferent,itreturnstrue.
if(this.textBox1.InvokeRequired)
{
SetTextCallbackd
=newSetTextCallback(SetText);
this.Invoke(d,newobject[]{text});
}

else
{
this.textBox1.Text=text;
}

}


//Thiseventhandlerstartstheform's
//BackgroundWorkerbycallingRunWorkerAsync.
//
//TheTextpropertyoftheTextBoxcontrolisset
//whentheBackgroundWorkerraisestheRunWorkerCompleted
//event.
privatevoidsetTextBackgroundWorkerBtn_Click(
objectsender,
EventArgse)
{
this.backgroundWorker1.RunWorkerAsync();
}


//ThiseventhandlersetstheTextpropertyoftheTextBox
//control.Itiscalledonthethreadthatcreatedthe
//TextBoxcontrol,sothecallisthread-safe.
//
//BackgroundWorkeristhepreferredwaytoperformasynchronous
//operations.

privatevoidbackgroundWorker1_RunWorkerCompleted(
objectsender,
RunWorkerCompletedEventArgse)
{
this.textBox1.Text=
"ThistextwassetsafelybyBackgroundWorker.";
}


WindowsFormDesignergeneratedcode#regionWindowsFormDesignergeneratedcode

privatevoidInitializeComponent()
{
this.textBox1=newSystem.Windows.Forms.TextBox();
this.setTextUnsafeBtn=newSystem.Windows.Forms.Button();
this.setTextSafeBtn=newSystem.Windows.Forms.Button();
this.setTextBackgroundWorkerBtn=newSystem.Windows.Forms.Button();
this.backgroundWorker1=newSystem.ComponentModel.BackgroundWorker();
this.SuspendLayout();
//
//textBox1
//
this.textBox1.Location=newSystem.Drawing.Point(12,12);
this.textBox1.Name="textBox1";
this.textBox1.Size=newSystem.Drawing.Size(240,20);
this.textBox1.TabIndex=0;
//
//setTextUnsafeBtn
//
this.setTextUnsafeBtn.Location=newSystem.Drawing.Point(15,55);
this.setTextUnsafeBtn.Name="setTextUnsafeBtn";
this.setTextUnsafeBtn.TabIndex=1;
this.setTextUnsafeBtn.Text="UnsafeCall";
this.setTextUnsafeBtn.Click+=newSystem.EventHandler(this.setTextUnsafeBtn_Click);
//
//setTextSafeBtn
//
this.setTextSafeBtn.Location=newSystem.Drawing.Point(96,55);
this.setTextSafeBtn.Name="setTextSafeBtn";
this.setTextSafeBtn.TabIndex=2;
this.setTextSafeBtn.Text="SafeCall";
this.setTextSafeBtn.Click+=newSystem.EventHandler(this.setTextSafeBtn_Click);
//
//setTextBackgroundWorkerBtn
//
this.setTextBackgroundWorkerBtn.Location=newSystem.Drawing.Point(177,55);
this.setTextBackgroundWorkerBtn.Name="setTextBackgroundWorkerBtn";
this.setTextBackgroundWorkerBtn.TabIndex=3;
this.setTextBackgroundWorkerBtn.Text="SafeBWCall";
this.setTextBackgroundWorkerBtn.Click+=newSystem.EventHandler(this.setTextBackgroundWorkerBtn_Click);
//
//backgroundWorker1
//
this.backgroundWorker1.RunWorkerCompleted+=newSystem.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
//
//Form1
//
this.ClientSize=newSystem.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]
staticvoidMain()
{
Application.EnableVisualStyles();
Application.Run(
newForm1());
}


}

}


在使用方法2时的注意事项: 不要将除了控件访问外其他逻辑代码放到委托的回调方法中.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值