zoukankan      html  css  js  c++  java
  • 解决线程不能访问用户界面组件的问题

    //因在项目的窗体文本框中要显示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;
            }

        }

    }
  • 相关阅读:
    椭圆形 上传图片预览 image preview (未整理版本)
    canvas学习笔记03:简单脉冲效果
    canvas学习笔记02:饼图&柱状图
    canvas学习笔记01:Math.sin & Math.cos
    java jdk 随机数阻塞问题
    家政/保洁 平台设计
    Lock和synchronized
    jvm 中java new 对象顺序
    Java 多线程原理
    java ftp上传下载,下载文件编码设置
  • 原文地址:https://www.cnblogs.com/kokoliu/p/519802.html
Copyright © 2011-2022 走看看