唐朝程序员

我来自唐朝

解决线程不能访问用户界面组件的问题

//因在项目的窗体文本框中要显示COM组件回调函数所传回来的值,
//谁知测试时竟然显示
//""System.InvalidOperationException: 线程间操作无效: 从不是创建控件“richTextBox1”的线程访问它。"
//或者干脆罢工,一个也不给你显示出来.让我大为恼火,毕竟"魔高一尺,道高一丈".于是对此做了些分析与测试.
//终于顺利解决.
//究其原因为: 在Windows From里面,需要在线程里面访问界面元素,需要使用BeginInvoke来完成.
//本示例通过调用cAdd类中的 GetAddResult() 方法,通过事件(AddComplete)实时触发传送计算结果 ,
//在窗体的richTextBox中显示出来.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace TestInteractiveThread
{
    
public delegate void AddHandler(int iResult);
    
public partial class Form1 : Form
    
{
        
private cAdd ca;
        
public Form1()
        
{
            InitializeComponent();
            ca 
= new cAdd();
            ca.AddComplete 
+= new AddHandler(ca_AddComplete);
        }


        
public delegate void InvokeInitDelegate(); //不带参数的委托
        public delegate void MyInitDelegate(RichTextBox myRtb, string strTemp); //带参数的异步委托

        
void ca_AddComplete(int iResult)
        
{
            
try
            
{
                
                
// this.richTextBox1.AppendText(Environment.NewLine + iResult.ToString());
                
//采用上面的方法将产生下面的错误.
                
//"System.InvalidOperationException: 线程间操作无效: 从不是创建控件“richTextBox1”的线程访问它。"


                
//在Windows From里面,需要在线程里面访问界面元素,需要使用BeginInvoke来完成.
                
//将上面的代码屏蔽掉,采用
                
//在创建控件的基础句柄所在线程上,用指定的参数异步执行指定委托。 
                this.richTextBox1.BeginInvoke(new MyInitDelegate(DelegateInitMethod), new object[] this.richTextBox1, iResult.ToString() });
            }

            
catch (System.Exception err)
            
{
                strErr 
= err.ToString();
               
                
//在创建控件的基础句柄所在线程上异步执行委托。在创建控件的基础句柄所在线程上异步执行指定委托。 
                
//由 .NET Compact Framework 支持。
                this.BeginInvoke(new InvokeInitDelegate(InvokeInitMethod));

                MessageBox.Show(err.ToString());
                
//throw new Exception("The method or operation is not implemented.");
            }

        }


        
private static string strErr = "";
        
private void InvokeInitMethod()
        
{
            
this.richTextBox1.AppendText(strErr);
        }


        
public void DelegateInitMethod(RichTextBox myRtb, string strTemp)
        
{
            myRtb.AppendText(System.Environment.NewLine 
+ strTemp);
        }


        
private void button_Test_Click(object sender, EventArgs e)
        
{
            
//ca.GetAddResult();  
            
//为了说明此问题我们采用下面的线程方法来调用.此时系统将弹出
            
//"System.InvalidOperationException: 线程间操作无效: 从不是创建控件“richTextBox1”的线程访问它。"
            System.Threading.Thread myThread = new System.Threading.Thread(
            
new System.Threading.ThreadStart(ca.GetAddResult));
            myThread.Start();


        }


        
private void button1_Click(object sender, EventArgs e)
        
{
            
this.richTextBox1.AppendText ( ca.AddInterlink(10).ToString() );
        }

       

    }

    
public class cAdd
    
{
        
public event AddHandler AddComplete;
        
public void GetAddResult()
        
{
            
int iResult=AddInterlink2(11);
            AddComplete(iResult);
        }

  
        
        
//1+1+2+3+5+8+13+21..+n
        private static int AddInterlink2(int i)
        
{
            
int[] x = new int[i+1];
            x[
0= 1;
            x[
1= 1;
            
for (int j = 2; j <= i; j++)
            
{
                x[j] 
= x[j - 1+ x[j - 2];
            }

            
return x[i];
        }


        
//也可采用下面的方法

        
private int x1=1,x2 = 1;
        
//1 + 1 + 2 + 3 + 5 + 8 + 13 + 21 +  + n
        
//x1,x2,  x1, x2, x1, x2, x1, x2,.
        
//x1,x2,  x3, x1, x2, x3, . 
        public  StringBuilder  AddInterlink(int i)
        
{
            StringBuilder s1 
= new StringBuilder();
            s1.Append(x1.ToString() 
+","+ x2.ToString()+","); ;
            
int j=2;
            
while (j < i)
            
{
                x1 
+= x2;
                x2 
+= x1;
                s1.Append(x1.ToString() 
+","+ x2.ToString()+",");   
                j
+=2;
            }

            
return s1;
        }

    }

}

posted on 2006-10-01 16:09  唐朝程序员  阅读(566)  评论(0编辑  收藏  举报

导航