C#线程中安全访问控件(重用委托,避免繁复的delegate,Invoke)总结
1.第一种,不安全,当线程过多后,timer控件和线程中同时访问窗体控件时,有时会出现界面重绘出错。
public frmMain()
{
InitializeComponent();
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls =false;
}
2.避免繁复的delegate,Invoke,转载,不推荐使用

public static class ControlCrossThreadCalls
{
public delegate void InvokeHandler(); ///<summary>
/// 线程安全访问控件,扩展方法 .net 3.5下用Lambda简化跨线程访问窗体控件,避免繁复的delegate,Invoke
/// this.SafeInvoke(() =>
/// {
/// tsStatus.Text = one.Email + " 开始任务....";
/// });
///</summary>
//public static void SafeInvoke(this Control control, InvokeHandler handler)
//{
// if (control.InvokeRequired)
// {
// control.Invoke(handler);
// }
// else
// {
// handler();
// }
//} ///<summary>
/// .net2.0线程安全访问扩展方法///</summary>
/// ControlCrossThreadCalls.SafeInvoke(this.tsStatus, new ControlCrossThreadCalls.InvokeHandler(delegate()
/// {
/// tsStatus.Text = one.Email + " 开始任务...";
/// }));
public static void SafeInvoke(Control control, InvokeHandler handler)
{
if (control.InvokeRequired)
{
control.Invoke(handler);
}
else
{
handler();
}
}
}

3.异步最新,推荐使用

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Threading; /// <summary>
/// 线程中安全访问控件,避免重复的delegate,Invoke
/// </summary>
public static class CrossThreadCalls
{
public delegate void TaskDelegate(); private delegate void InvokeMethodDelegate(Control control, TaskDelegate handler); /// <summary>
/// .net2.0中线程安全访问控件扩展方法,可以获取返回值,可能还有其它问题
/// </summary>
/// CrossThreadCalls.SafeInvoke(this.statusStrip1, new CrossThreadCalls.TaskDelegate(delegate()
/// {
/// tssStatus.Text = "开始任务...";
/// }));
/// CrossThreadCalls.SafeInvoke(this.rtxtChat, new CrossThreadCalls.TaskDelegate(delegate()
/// {
/// rtxtChat.AppendText("测试中");
/// }));
/// 参考:http://wenku.baidu.com/view/f0b3ac4733687e21af45a9f9.html
/// <summary>
public static void SafeInvoke(Control control, TaskDelegate handler)
{
if (control.InvokeRequired)
{
while (!control.IsHandleCreated)
{
if (control.Disposing || control.IsDisposed)
return;
}
IAsyncResult result = control.BeginInvoke(new InvokeMethodDelegate(SafeInvoke), new object[] { control, handler });
control.EndInvoke(result);//获取委托执行结果的返回值
return;
}
IAsyncResult result2 = control.BeginInvoke(handler);
control.EndInvoke(result2);
} /// <summary>
/// 线程安全访问控件,扩展方法.net3.5用Lambda简化跨线程访问窗体控件,避免重复的delegate,Invoke
/// this.statusStrip1.SafeInvoke(() =>
/// {
/// tsStatus.Text = "开始任务....";
/// });
/// this.rtxtChat.SafeInvoke(() =>
/// {
/// rtxtChat.AppendText("测试中");
/// });
/// </summary>
//public static void SafeInvoke(this Control control, TaskDelegate handler)
//{
// if (control.InvokeRequired)
// {
// while (!control.IsHandleCreated)
// {
// if (control.Disposing || control.IsDisposed)
// return;
// }
// IAsyncResult result = control.BeginInvoke(new InvokeMethodDelegate(SafeInvoke), new object[] { control, handler });
// control.EndInvoke(result);//获取委托执行结果的返回值
// return;
// }
// IAsyncResult result2 = control.BeginInvoke(handler);
// control.EndInvoke(result2);
//}

更正一个我发现的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很高,内存成倍增长。
C#线程中安全访问控件(重用委托,避免繁复的delegate,Invoke)总结的更多相关文章
- C#学习之在辅助线程中修改UI控件----invoke方法
Invoke and BeginInvoke 转载地址:http://www.cnblogs.com/worldreason/archive/2008/06/09/1216127.html 在Invo ...
- C#中禁止跨线程直接访问控件
C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它.此时它将会在内部调用ne ...
- [C#] Control.Invoke方法和跨线程访问控件(转载)
转载前,在网上找了好多INVOKE方法的文章,就这个看着还可以,明白了大概,以后再深用的时候再研究 ,废话少说上转载(连转载都说的这么有气势,哈哈) 在设计界面时,我们经常需要将一些需要时间才能完 ...
- C#中跨线程访问控件问题解决方案
net 原则上禁止跨线程访问控件,因为这样可能造成错误的发生,推荐的解决方法是采用代理,用代理方法来间接操作不是同一线程创建的控件. 第二种方法是禁止编译器对跨线程访问作检查,可以实现访问,但是出不出 ...
- [C#] Control.Invoke方法和跨线程访问控件
在设计界面时,我们经常需要将一些需要时间才能完成的操作放在另一个线程(不同于UI主线程)中执行.但是这些操作可能需要将其结果或完成情况通知主线程,比如调用窗体的方法,或者触发事件(由界面响应事件),很 ...
- C#之Winform跨线程访问控件
C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它.此时它将会在内部调用ne ...
- C#中跨线程访问控件
net 原则上禁止跨线程访问控件,因为这样可能造成错误的发生,推荐的解决方法是采用代理,用代理方法来间接操作不是同一线程创建的控件. 第二种方法是禁止编译器对跨线程访问作检查,可以实现访问,但是出不出 ...
- c#跨线程访问控件帮助类
1.背景 对于winform程序来说,当我们点击按钮,需要消耗一定时长才能拿到数据后才能显示在界面上某个控件上的情况,我们通常会专门开一个线程去拿数据,这样不会造成界面处于假死状态 2.常规做法 // ...
- C# WinFrom 跨线程访问控件
1.跨线程访问控件委托和类的定义 using System; using System.Windows.Forms; namespace ahwildlife.Utils { /// <summ ...
随机推荐
- 关于<input type="hidden"/>标签的记录
<input type="hidden" name="pid" value="10"/>标签放在一个input标签后可以使用,但 ...
- 4Linux 终端命令格式
Linux 终端命令格式 转自 目标 了解终端命令格式 知道如何查阅终端命令帮助信息 01. 终端命令格式 command [-options] [parameter] 说明: command:命令名 ...
- [易学易懂系列|golang语言|零基础|快速入门|(一)]
golang编程语言,是google推出的一门语言. 主要应用在系统编程和高性能服务器编程,有广大的市场前景,目前整个生态也越来越强大,未来可能在企业应用和人工智能等领域占有越来越重要的地位. 本文章 ...
- 磁盘,fdisk分区,MBR,dd命令
光盘和磁盘.u盘.软盘.硬盘有什么区别 ①光盘: cdrom/dvdrom:光驱(光盘驱动器) rom:只读 ram:可以擦写 cd:700M dvd:4G ②软盘:flopp ...
- git概述(二)
分支管理 分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了.如果等代码全部写完再一次 ...
- 链表中倒数第k个节点(python)
题目描述 输入一个链表,输出该链表中倒数第k个结点. 无力吐槽牛客网... class Solution: def FindKthToTail(self, head, k): # write code ...
- Installing MacOS to VirtualBox
https://medium.com/@twister.mr/installing-macos-to-virtualbox-1fcc5cf22801
- linux运维、架构之路-Hadoop完全分布式集群搭建
一.介绍 Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS.HDFS有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件 ...
- css-外面元素的高度,由里面的元素进行撑开(由内部的高度决定)
1.删除你的高度的固定值 2.将父元素的====>display:inline-block; 或者设置浮动====>float:left;
- JSP文件的上传和下载
文件上传下载,与传统的方式不同,这里能够上传和下载10G以上的文件.而且支持断点续传. 通常情况下,我们在网站上面下载的时候都是单个文件下载,但是在实际的业务场景中,我们经常会遇到客户需要批量下载的场 ...