三种方法来解决跨线程访问控件的问题.doc_第1页
三种方法来解决跨线程访问控件的问题.doc_第2页
三种方法来解决跨线程访问控件的问题.doc_第3页
三种方法来解决跨线程访问控件的问题.doc_第4页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

访问 Windows 窗体控件本质上不是线程安全的。如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致的状态。还可能出现其他与线程相关的 bug,包括争用情况和死锁。确保以线程安全方式访问控件非常重要。.NET Framework 有助于在以非线程安全方式访问控件时检测到这一问题。在调试器中运行应用程序时,如果创建某控件的线程之外的其他线程试图调用该控件,则调试器会引发一个 InvalidOperationException,并提示消息:“从不是创建控件 control name 的线程访问它。”此异常在调试期间和运行时的某些情况下可靠地发生。强烈建议您在显示此错误信息时修复此问题。在调试以 .NET Framework 2.0 版之前的 .NET Framework 编写的应用程序时,可能会出现此异常。注意可以通过将 CheckForIllegalCrossThreadCalls 属性的值设置为 false 来禁用此异常。这会使控件以与在 Visual Studio 2003 下相同的方式运行。下面的代码示例演示如何从辅助线程以线程安全方式和非线程安全方式调用 Windows 窗体控件。它演示一种以非线程安全方式设置TextBox控件的Text属性的方法,还演示两种以线程安全方式设置 Text 属性的方法。using System;using System.ComponentModel;using System.Threading;using System.Windows.Forms;namespace CrossThreadDemopublic class Form1 : Form/ 代理实现异步调用以设置TextBox控件text属性delegate void SetTextCallback(string text);/ 此线程用来演示线程安全和非安全两种方式来调用一个windows窗体控件private Thread demoThread = null;/ 此后台工作者(BackgroundWorker)用来演示执行异步操作的首选方式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);/ 此事件句柄创建一个ie线程以非安全方式调用一个windows窗体控件private void setTextUnsafeBtn_Click(object sender,EventArgs e)this.demoThread =new Thread(new ThreadStart(this.ThreadProcUnsafe);this.demoThread.Start();/ 此方法在工作者线程执行并且对TextBox控件作非安全调用private void ThreadProcUnsafe()this.textBox1.Text = This text was set unsafely.;/ 此事件句柄创建一个以线程安全方式调用windows窗体控件的线程private void setTextSafeBtn_Click(object sender,EventArgs e)this.demoThread =new Thread(new ThreadStart(this.ThreadProcSafe);this.demoThread.Start();/ 此方法在工作者线程执行并且对TextBox控件作线程安全调用private void ThreadProcSafe()this.SetText(This text was set safely.);/ 此方法演示一个对windows窗体控件作线程安全调用的模式/ 如果调用线程和创建TextBox控件的线程不同,这个方法创建/ 代理SetTextCallback并且自己通过Invoke方法异步调用它/ 如果相同则直接设置Text属性private void SetText(string text)/ InvokeRequired需要比较调用线程ID和创建线程ID/ 如果它们不相同则返回trueif (this.textBox1.InvokeRequired)SetTextCallback d = new SetTextCallback(SetText);this.Invoke(d, new object text );elsethis.textBox1.Text = text;/ 此事件句柄通过调用RunWorkerAsync开启窗体的BackgroundWorker/ 当BackgroundWorker引发RunworkerCompleted事件的时候TextBox/ 控件的Text属性被设置private void setTextBackgroundWorkerBtn_Click(object sender,EventArgs e)this.backgroundWorker1.RunWorkerAsync();/ 此事件句柄设置TextBox控件的Text属性,它在创建TextBox控件的线程/ 中被调用,所以它的调用是线程安全的/ BackgroundWorker是执行异步操作的首选方式private void backgroundWorker1_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)this.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();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);/Form1this.ClientSize = new System.Drawing.Size(268, 96);this.Controls.Add(this.setTextBackgroundWorkerBtn);this.Controls.Add(this.setTextSafeBtn);this.Controls.Ad

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论