C#线程中安全访问控件总结

简介: C#线程中安全访问控件(重用委托,避免繁复的delegate,Invoke)总结 1.第一种,不安全,当线程过多后,timer控件和线程中同时访问窗体控件时,有时会出现界面重绘出错。

C#线程中安全访问控件(重用委托,避免繁复的delegate,Invoke)总结

1.第一种,不安全,当线程过多后,timer控件和线程中同时访问窗体控件时,有时会出现界面重绘出错。

public frmMain()
 {
     InitializeComponent();
     System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls =false;
 }

2.避免繁复的delegate,Invoke,推荐

  1. public static class ControlCrossThreadCalls
  2. {
  3.     public delegate void InvokeHandler();

  4.     ///
  5.     /// 线程安全访问控件,扩展方法 .net 3.5下用Lambda简化跨线程访问窗体控件,避免繁复的delegate,Invoke
  6.     /// this.SafeInvoke(() =>
  7.     /// {
  8.     /// tsStatus.Text = one.Email + " 开始任务....";
  9.     /// });
  10.     ///
  11.     //public static void SafeInvoke(this Control control, InvokeHandler handler)
  12.     //{
  13.     // if (control.InvokeRequired)
  14.     // {
  15.     // control.Invoke(handler);
  16.     // }
  17.     // else
  18.     // {
  19.     // handler();
  20.     // }
  21.     //}

  22.     ///
  23.     /// .net2.0线程安全访问扩展方法///
  24.     /// ControlCrossThreadCalls.SafeInvoke(this.tsStatus, new ControlCrossThreadCalls.InvokeHandler(delegate()
  25.     /// {
  26.     /// tsStatus.Text = one.Email + " 开始任务...";
  27.     /// }));
  28.     public static void SafeInvoke(Control control, InvokeHandler handler)
  29.     {
  30.         if (control.InvokeRequired)
  31.         {
  32.             control.Invoke(handler);
  33.         }
  34.         else
  35.         {
  36.             handler();
  37.         }
  38.     }
  39. }


 最新代码如下

  1. public static class CrossThreadCalls
  2. {
  3.     public delegate void InvokeHandler();

  4.     ///
  5.     /// .net2.0中线程安全访问控件扩展方法,可以获取返回值,可能还有其它问题
  6.     ///
  7.     /// CrossThreadCalls.SafeInvoke(this.statusStrip1, new CrossThreadCalls.InvokeHandler(delegate()
  8.     /// {
  9.     /// tssStatus.Text = "开始任务...";
  10.     /// }));
  11.     /// CrossThreadCalls.SafeInvoke(this.rtxtChat, new CrossThreadCalls.InvokeHandler(delegate()
  12.     /// {
  13.     /// rtxtChat.AppendText("测试中");
  14.     /// }));
  15.     /// 参考:http://wenku.baidu.com/view/f0b3ac4733687e21af45a9f9.html
  16.     ///
  17.     public static void SafeInvoke(Control control, InvokeHandler handler)
  18.     {
  19.         if (control.InvokeRequired)
  20.         {
  21.             while (!control.IsHandleCreated)
  22.             {
  23.                 if (control.Disposing || control.IsDisposed)
  24.                     return;
  25.             }
  26.             //control.Invoke(handler);
  27.             IAsyncResult result = control.BeginInvoke(handler);
  28.             control.EndInvoke(result);//获取委托执行结果的返回值
  29.         }
  30.         else
  31.         {
  32.             handler();
  33.         }
  34.     }

  35.     ///
  36.     /// 线程安全访问控件,扩展方法.net3.5用Lambda简化跨线程访问窗体控件,避免重复的delegate,Invoke
  37.     /// this.statusStrip1.SafeInvoke(() =>
  38.     /// {
  39.     /// tsStatus.Text = "开始任务....";
  40.     /// });
  41.     /// this.rtxtChat.SafeInvoke(() =>
  42.     /// {
  43.     /// rtxtChat.AppendText("测试中");
  44.     /// });
  45.     ///
  46.     //public static void SafeInvoke(this Control control, InvokeHandler handler)
  47.     //{
  48.     // if (control.InvokeRequired)
  49.     // {
  50.     // control.Invoke(handler);
  51.     // }
  52.     // else
  53.     // {
  54.     // handler();
  55.     // }
  56.     //}
  57. }


更正一个我发现的C#多线程安全访问控件普遍存在的问题,仅供参考,在网上搜索多线程访问控件,发现很多都是这种类似的写法

http://msdn.microsoft.com/zh-cn/library/ms171728.aspx

复制代码
    private void SetText(string text)
    { // InvokeRequired required compares the thread ID of the // calling thread to the thread ID of the creating thread. // If these threads are different, it returns true. if (this.textBox1.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text });
        } else { this.textBox1.Text = text;
        }
    }
复制代码

注意红色部分,这样写几个线程同时操作时问题不是很大,但是当我几10个几100个线程频繁操作时,就出现了System.OutOfMemoryException这个异常,猜测可能是线程堵塞,同时造成cpu很高,内存成倍增长。


来自博客:
http://www.cnblogs.com/slyzly/articles/2121436.html

相关文章
|
4月前
|
机器学习/深度学习 监控 算法
局域网行为监控软件 C# 多线程数据包捕获算法:基于 KMP 模式匹配的内容分析优化方案探索
本文探讨了一种结合KMP算法的多线程数据包捕获与分析方案,用于局域网行为监控。通过C#实现,该系统可高效检测敏感内容、管理URL访问、分析协议及审计日志。实验表明,相较于传统算法,KMP在处理大规模网络流量时效率显著提升。未来可在算法优化、多模式匹配及机器学习等领域进一步研究。
110 0
|
9月前
|
监控 Kubernetes Java
阿里面试:5000qps访问一个500ms的接口,如何设计线程池的核心线程数、最大线程数? 需要多少台机器?
本文由40岁老架构师尼恩撰写,针对一线互联网企业的高频面试题“如何确定系统的最佳线程数”进行系统化梳理。文章详细介绍了线程池设计的三个核心步骤:理论预估、压测验证和监控调整,并结合实际案例(5000qps、500ms响应时间、4核8G机器)给出具体参数设置建议。此外,还提供了《尼恩Java面试宝典PDF》等资源,帮助读者提升技术能力,顺利通过大厂面试。关注【技术自由圈】公众号,回复“领电子书”获取更多学习资料。
|
12月前
|
SQL 开发框架 .NET
C#一分钟浅谈:数据绑定与数据源控件
在Web开发中,数据绑定和数据源控件是实现动态网页的关键技术。本文从基础概念入手,详细讲解数据绑定的原理及其在ASP.NET中的应用,并介绍常见数据绑定方式:手动绑定和自动绑定。接着,文章重点介绍了ASP.NET中的数据源控件,如`SqlDataSource`、`ObjectDataSource`、`XmlDataSource`和`LinqDataSource`,并通过具体示例演示如何使用`SqlDataSource`和`GridView`进行数据绑定。最后,还列举了一些常见问题及其解决办法,帮助读者更好地理解和应用这些技术。
177 4
|
数据采集 XML JavaScript
C# 中 ScrapySharp 的多线程下载策略
C# 中 ScrapySharp 的多线程下载策略
|
10月前
|
缓存 安全 Java
【JavaEE】——单例模式引起的多线程安全问题:“饿汉/懒汉”模式,及解决思路和方法(面试高频)
单例模式下,“饿汉模式”,“懒汉模式”,单例模式下引起的线程安全问题,解锁思路和解决方法
|
10月前
|
Java 调度
【JavaEE】——线程的安全问题和解决方式
【JavaEE】——线程的安全问题和解决方式。为什么多线程运行会有安全问题,解决线程安全问题的思路,synchronized关键字的运用,加锁机制,“锁竞争”,几个变式
|
11月前
|
C# Python
使用wxpython开发跨平台桌面应用,对wxpython控件实现类似C#扩展函数处理的探究
【10月更文挑战第30天】使用 `wxPython` 开发跨平台桌面应用时,可以通过创建辅助类来模拟 C# 扩展函数的功能。具体步骤包括:1. 创建辅助类 `WxWidgetHelpers`;2. 在该类中定义静态方法,如 `set_button_color`;3. 在应用中调用这些方法。这种方法提高了代码的可读性和可维护性,无需修改 `wxPython` 库即可为控件添加自定义功能。但需要注意显式调用方法和避免命名冲突。
|
SQL 存储 关系型数据库
C#一分钟浅谈:使用 ADO.NET 进行数据库访问
【9月更文挑战第3天】在.NET开发中,与数据库交互至关重要。ADO.NET是Microsoft提供的用于访问关系型数据库的类库,包含连接数据库、执行SQL命令等功能。本文从基础入手,介绍如何使用ADO.NET进行数据库访问,并提供示例代码,同时讨论常见问题及其解决方案,如连接字符串错误、SQL注入风险和资源泄露等,帮助开发者更好地利用ADO.NET提升应用的安全性和稳定性。
662 6
【Java集合类面试十二】、HashMap为什么线程不安全?
HashMap在并发环境下执行put操作可能导致循环链表的形成,进而引起死循环,因而它是线程不安全的。