精华内容
下载资源
问答
  • C# WinForm 跨线程访问控件 在做WinFrom开发的时候,经常会遇到跨线程访问控件的问题,即从不是创建控件的线程去访问控件。百度里面搜索,会有各种各样的解决方案。在诸多方案中,我认为没有一个方案是特别简单,...

    C# WinForm 跨线程访问控件
    在做WinFrom开发的时候,经常会遇到跨线程访问控件的问题,即从不是创建控件的线程去访问控件。百度里面搜索,会有各种各样的解决方案。在诸多方案中,我认为没有一个方案是特别简单,而且代码量少的。以前我也傻傻的创建委托(当然也尝试过其它方法),当数量多了以后,发现代码不整洁。今天,我就跟大家分享一下我的方法(至少我没发现别人用这种方法),不正之处,欢迎批评指正。
    演示代码

            /// <summary>
            /// 摘要:
            ///    修改Button控件文字(仅供演示)
            /// </summary>
            private void ChangeBtnText(string Text)
            {
                Action DoAction = delegate()
                {
                    Btn.Text = Text;
                };
    
                if (this.InvokeRequired)
                {
                    ControlExtensions.UIThreadInvoke(this, delegate
                    {
                        DoAction();
                    });
                }
                else
                {
                    DoAction();
                }
            }
    

    辅助静态类代码

        /// <summary>
        /// 摘要:
        ///    跨线程访问UI通用组件,在此类外的Try Catch语句不能捕获委托中的错误。
        /// </summary>
        static class ControlExtensions
        {
            /// <summary>
            /// 同步执行 注:外层Try Catch语句不能捕获Code委托中的错误
            /// </summary>
            static public void UIThreadInvoke(this Control control, Action Code)
            {
                try
                {
                    if (control.InvokeRequired)
                    {
                        control.Invoke(Code);
                        return;
                    }
                    Code.Invoke();
                }
                catch 
                {
                    /*仅捕获、不处理!*/
                }
            }
    
            /// <summary>
            /// 异步执行 注:外层Try Catch语句不能捕获Code委托中的错误
            /// </summary>
            static public void UIThreadBeginInvoke(this Control control, Action Code)
            {
                if (control.InvokeRequired)
                {
                    control.BeginInvoke(Code);
                    return;
                }
                Code.Invoke();
            }
        }
    

    我认为这种写法是一劳永逸的,在解决问题的同时,代码量是最少的而且逻辑清楚代码整洁。关键是用这个方法去重构或者优化以前的代码是最省事的。你只需要将你以前的代码全部放到Action委托中,按这种模式套就可以了。

    主要研发方向:Tcp,TcpNat,服务前端,反向连接,大规范并发
    QQ交流群:697622527 欢迎交流

    展开全文
  • //创建委托 public delegate void UpdateTxt(int line_now,string states,int color,int num);//创建一个委托 //定义委托变量 public UpdateTxt updateTxt_ok; public Form1() { InitializeC...

    //创建委托
    public delegate void UpdateTxt(int line_now,string states,int color,int num);//创建一个委托

    //定义委托变量
    public UpdateTxt updateTxt_ok;

     

    public Form1()
    {
      InitializeComponent();

      //实例化委托
      updateTxt_ok = new UpdateTxt(UpdateTxtMethod);
    }

     

    public void UpdateTxtMethod(int line_now,string states,int color,int num)
    {

      /*

       *  跨线程调用控件code

       */

    }

     

    //开启线程

    int[] arr = new int[] { k, thread_total };
    Thread objThread = new Thread(new ThreadStart(delegate
    {
      this.BeginInvoke(updateTxt_ok(参数1,参数2,参数3));
    }));
    objThread.Start();

     

     

     

     

     

    带参数的委托

     

     

    //创建委托

    public delegate void UpdateTxt(int line_now,string states,int color,int num);//创建一个委托

    //定义委托变量
    public UpdateTxt updateTxt_ok;

     

    //委托函数

    public void UpdateTxtMethod(int line_now,string states,int color,int num)
    {

      /*

       *  跨线程调用控件code

       */

    }

     

     

    this.BeginInvoke(updateTxt_ok,int line_now,string states,int color,int num);

     

    转载于:https://www.cnblogs.com/longzhankunlun/p/6725262.html

    展开全文
  • 因此,当没有使用委托机制而是直接在子线程中修改控件内容时,会引发控件安全问题,即跨线程访问控件问题。 所谓跨线程调用控件就是一个线程调用另外一个线程的控件。 常见使用情况,比如:当我们开了一个在后台...

    跨线程访问控件问题的原因是:控件都是在主线程中创建的,而系统默认控件的修改权归其创建线程所有。在子线程中如果需要直接修改控件的内容,需要使用委托机制将控件的修改操作交给主线程处理。因此,当没有使用委托机制而是直接在子线程中修改控件内容时,会引发控件安全问题,即跨线程访问控件问题。

    所谓跨线程调用控件就是一个线程调用另外一个线程的控件。

    常见使用情况,比如:当我们开了一个在后台监听消息的线程以后,需要将消息内容添加到主窗体的消息框内显示出来。

    这时候,我们就需要使用跨线程调用控件的方法。

    1.首先,声明一个委托,如:
    //修饰符 delegate 返回类型 委托函数名(有参/无参);
    public delegate void AddInfo_Delgegate(string message);
    2.创建委托函数对象,如:

    //添加消息到指定控件的函数
    private void AddInfo(string message)
    {
    this.richTextBox_Message.Text += message;
    this.richTextBox_Message.Text += "\r\n";//换行
    }

    AddInfo_Delegate addinfo = new AddInfo_Delegate(AddInfo);

    3.在需要跨线程调用空间的地方,使用invoke方法:


    this.richTextBox_Message.Invoke(addinfoDelegate, DELEGATEMESSAGE);
    //this.richTextBox_Message 是需要添加消息的控件
    //invoke() 正如官方解释所说,在拥有此控件的线程上,调用指定参数列表执行委托。
    //invoke() 有两种参数模式,一是invoke(委托函数对象),二是带参类型invoke(委托函数对象,参数)
    ---------------------
    作者:linyujie0927
    来源:CSDN
    原文:https://blog.csdn.net/linyujie0927/article/details/72083227
    版权声明:本文为博主原创文章,转载请附上博文链接!

    转载于:https://www.cnblogs.com/asdyzh/p/9876818.html

    展开全文
  • .net 2.0以后加强了安全机制,不允许在winform中直接跨线程访问控件的属性,会提示错误“跨线程操作无效“。 提供几种方法解决这个问题 1. 设置CheckForIllegalCrossThreadCalls为False ...

    .net 2.0以后加强了安全机制,不允许在winform中直接跨线程访问控件的属性,会提示错误“跨线程操作无效“。

    提供几种方法解决这个问题

    1. 设置CheckForIllegalCrossThreadCalls为False

    CheckForIllegalCrossThreadCalls为全局静态变量,设置为False后程序就不检查跨线程的调用是否合法

    2、delegate委托

    假设需要在更新控件Label1的Text

    private void button1_Click(object sender, EventArgs e)
    {
        Thread thread1 = new Thread(new ParameterizedThreadStart(UpdateLabel1));
        thread1.Start("更新Label");
    }         
    

    (1)搭配invoke

    private void UpdateLabel1(object str)
    {
        if (label2.InvokeRequired)
        {
            // 当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它
            Action<string> actionDelegate = (x) => { this.Label1.Text = x.ToString(); };
            // 或者
            // Action<string> actionDelegate = delegate(string txt) { this.Label1.Text = txt; };
            this.Label1.Invoke(actionDelegate, str);
        }
        else
        {
            this.Label1.Text = str.ToString();
        }
    }
    

    (2)搭配BeginInvoke

    private void UpdateLabel1(object str)
    {
        if (label2.InvokeRequired)
        {
            // 当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它
            Action<string> actionDelegate = (x) => { this.Label1.Text = x.ToString(); };
            // 或者
            // Action<string> actionDelegate = delegate(string txt) { this.Label1.Text = txt; };
            this.Label1.BeginInvoke(actionDelegate, str);
        }
        else
        {
            this.label2.Text = str.ToString();
        }
    }
    

    Invoke方法是同步的, 它会等待工作线程完成,

    BeginInvoke方法是异步的, 它会另起一个线程去完成工作线程

    3、BackgroundWorker组件

    private void button1_Click(object sender, EventArgs e)
    {
        using (BackgroundWorker bw = new BackgroundWorker())
        {
            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerAsync("Tank");
        }         
    }
    
    void bw_DoWork(object sender, DoWorkEventArgs e)
    {       
        // 这里是后台线程, 是在另一个线程上完成的
        // 这里是真正做事的工作线程
        // 可以在这里做一些费时的,复杂的操作
        Thread.Sleep(5000);
        e.Result = e.Argument + "工作线程完成";
    }
    
    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        //这时后台线程已经完成,并返回了主线程,所以可以直接使用UI控件了 
        this.Label1.Text = e.Result.ToString(); 
    }
    

    转载于:https://my.oschina.net/ZhangYaqing/blog/1547730

    展开全文
  • C#跨线程访问控件处理方式

    千次阅读 2018-06-19 14:40:23
    C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件A(由线程Tread A创建)的InvokeRequired属性值为真时,说明有一个创建它以外的线程(Tread B)想访问它。此时,若Tread B线程...
  • 1、跨线程访问控件委托和类的定义 using System; using System.Windows.Forms; namespace ahwildlife.Utils { /// <summary> /// 跨线程访问控件委托 /// </summary> public ...
  • C# WinForm 跨线程访问控件

    千次阅读 2013-08-13 14:57:08
    然而我们并不能用传统方法来访问界面上的控件c#中禁止跨线程直接访问控件,InvokeRequired就是为了解决这个问题而产生的。  Control.InvokeRequired   获取一个值,该值指示调用方在对控件进行方法调用时是否...
  • C#异步委托跨线程访问控件

    千次阅读 2018-11-24 21:24:45
    C#异步委托跨线程访问控件欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、...
  • C#跨线程访问控件

    2013-03-17 14:28:48
    C#跨线程访问控件,用了线程池和Action委托和Control的Invoke方法
  • 本文实例讲述了C#中WinForm跨线程访问控件的实现方法,分享给大家供大家参考。 具体实现方法如下: 1、跨线程访问控件委托和类的定义 代码如下:using System; using System.Windows.Forms; namespace ahwildlife....
  • 多线程应用中经常要跨线程访问窗体控件, 但在 C#中是不允许直接从非拥有控件的线程中访问控件的, 必须通过委托的方式安全调用, 如下示例所示: public partial class Form1 : Form { public Form1() { ...
  • 多线程应用中经常要跨线程访问窗体控件, 但在 C#中是不允许直接从非拥有控件的线程中访问控件的, 必须通过委托的方式安全调用, 如下示例所示:  public partial class Form1 : Form  {  public Form1()  { ...
  • C#编程中跨线程访问控件一、简述二、Winforms中跨线程访问控件三、WPF中跨线程访问控件参考文档 一、简述 C#中不允许跨线程直接访问界面控件,即一个线程中如主线程创建的控件不允许被其他线程例如子线程直接访问,...
  • C# 跨线程访问控件

    千次阅读 2018-04-06 00:21:08
    因为C#安全机制的问题,不是本线程创建的控件,是不能...二、创建委托,利用C#的Invoke 或 beginInvoke 方法从创建控件的线程来执行跨线程调用; 三、利用BackgroundWorker组件 和 DoWorkEventHandler 、 RunWorker...
  • 来源:https://www.cnblogs.com/PatrickLiu/p/7094616.html //申明一个委托对象  public delegate void Action2<in T>(T t); private void button1_Click(object sender, EventArgs e) { ...
  • 里面包含了刷新lable控件的数据和创建lable控件 其中Begininvoke属于是异步,Invoke属于同步  public delegate void update_lable(string str);  static update_lable update_lable_object;
  • WinForm(C#)中跨线程访问控件的解决方法 由于多线程可能导致对控件访问的不一致,导致出现问题。C#中默认是要线程安全的,即在访问控件时需要首先判断是否跨线程,如果是跨线程的直接访问,在运行时会抛出异常。 ...
  • 最近使用到了跨线程操作winform控件时候,用到了invoke和begin invoke时候,发现我的代码里使用invoke和begininvoke都不影响执行。这里是关于跨线程操作的参考文章 Invoke和BeginInvoke的定义 invoke的定义是...
  • C#跨线程操作控件

    2020-03-19 17:42:52
    C#跨线程操作控件是不允许的,有两种解决方式,实现方式都是一样的,都是通过异步和委托实现 第一种 直接使用异步和委托,如: this.BeginInvoke(new MethodInvoker(delegate { //这里写要进行操作的具体代码 ...
  • c#跨线程访问控件

    2019-04-23 11:31:23
    还是使用demo的形式来说下如何访问控件,先看下我们想要的效果 实现思路 任务1和任务2采用两个线程,将每次运算结果显示在lable中,我们先按自己的思路写下看能不能实现。 private void button1_Click(object ...
  • c# 跨线程访问控件

    2020-09-29 20:22:50
    这样可以实现在另外的线程访问控件,但是这种方法并不安全,不能保证C#跨线程访问控件的运行时错误。 // 在初始化控件后就可以把这个属性设置为false,编译器就不会对跨线程访问做检查 public Form1() { Initialize...
  • c#跨线程使用控件

    2019-10-04 21:10:14
    c#跨线程使用控件需要使用委托来实现 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; ...
  • C#跨线程修改控件

    2021-02-20 16:53:49
    c#跨线程访问修改控件会报错,此时解决方法之一就是用委托,下面代码实现了利用委托方式赋值checkbox delegate void SetBoolCallback(bool sate) private void SetBool(bool state) { if(this.InvokeRequired) { ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,919
精华内容 1,167
关键字:

c#委托跨线程访问控件

c# 订阅