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 ...
随机推荐
- TCP/IP四层协议
1.数据链路层 数据链路层实现了网卡接口的网络驱动程序,处理数据在物理媒介(以太网,令牌环)上的传输,常用协议包含ARP(地址解析协议),RARP(逆地址解析协议)两个协议,他们实现了IP地址和物理地 ...
- 30. Substring with Concatenation of All Words (JAVA)
You are given a string, s, and a list of words, words, that are all of the same length. Find all sta ...
- logname - 显示用户登录名
总览 (SYNOPSIS) logname [OPTION]... 描述 (DESCRIPTION) 显示 当前用户 的 名字. --help 显示 帮助信息, 然后 结束. --version 显示 ...
- Educational Codeforces Round 55 (Rated for Div. 2) B. Vova and Trophies (贪心+字符串)
B. Vova and Trophies time limit per test2 seconds memory limit per test256 megabytes inputstandard i ...
- Codeforces 矩阵题 题单
Matrix CF 166E Tetrahedron dp方程设为 f[i] 最后在 D点,g[i] 表示最后不在D点.最后 g[] 可以通过矩阵加速数列求得,数据可以强化,复杂度 \(O(logn) ...
- DDD领域驱动设计初探(二):仓储Repository(上)
前言:上篇介绍了DDD设计Demo里面的聚合划分以及实体和聚合根的设计,这章继续来说说DDD里面最具争议的话题之一的仓储Repository,为什么Repository会有这么大的争议,博主认为主要原 ...
- VS2015开发常用快捷键
以下内容均Ctrl+后面的按钮 M-O\P折叠 K-F 格式化 K-U\C注释 K-S侧外代码-(区域代码) 代码片段 ctor 自动生成默认的构造函数 prop 自动生成get set方法 cw 自 ...
- heroinfo_set.all 函数
如果是 一对多 关系 即使用 heroinfo_set.all 此时关联字段类型通用,即上边的字段通用,但是需要添加many=True的参数heroinfo_set = serializers.Pr ...
- k-means原理和python代码实现
k-means:是无监督的分类算法 k代表要分的类数,即要将数据聚为k类; means是均值,代表着聚类中心的迭代策略. k-means算法思想: (1)随机选取k个聚类中心(一般在样本集中选取,也可 ...
- CSS颜色和长度单位
颜色 如果我们相给页面设置颜色可以采用多种方法进行设置: 一.命名颜色 假设在设置页面的颜色时觉得一部分很小的颜色集中就足够了,就可以直接给定颜色的名称.CSS称这些有名称的颜色为命名颜色. 命名颜色 ...