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)总结的更多相关文章

  1. C#学习之在辅助线程中修改UI控件----invoke方法

    Invoke and BeginInvoke 转载地址:http://www.cnblogs.com/worldreason/archive/2008/06/09/1216127.html 在Invo ...

  2. C#中禁止跨线程直接访问控件

    C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它.此时它将会在内部调用ne ...

  3. [C#] Control.Invoke方法和跨线程访问控件(转载)

    转载前,在网上找了好多INVOKE方法的文章,就这个看着还可以,明白了大概,以后再深用的时候再研究 ,废话少说上转载(连转载都说的这么有气势,哈哈)   在设计界面时,我们经常需要将一些需要时间才能完 ...

  4. C#中跨线程访问控件问题解决方案

    net 原则上禁止跨线程访问控件,因为这样可能造成错误的发生,推荐的解决方法是采用代理,用代理方法来间接操作不是同一线程创建的控件. 第二种方法是禁止编译器对跨线程访问作检查,可以实现访问,但是出不出 ...

  5. [C#] Control.Invoke方法和跨线程访问控件

    在设计界面时,我们经常需要将一些需要时间才能完成的操作放在另一个线程(不同于UI主线程)中执行.但是这些操作可能需要将其结果或完成情况通知主线程,比如调用窗体的方法,或者触发事件(由界面响应事件),很 ...

  6. C#之Winform跨线程访问控件

    C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它.此时它将会在内部调用ne ...

  7. C#中跨线程访问控件

    net 原则上禁止跨线程访问控件,因为这样可能造成错误的发生,推荐的解决方法是采用代理,用代理方法来间接操作不是同一线程创建的控件. 第二种方法是禁止编译器对跨线程访问作检查,可以实现访问,但是出不出 ...

  8. c#跨线程访问控件帮助类

    1.背景 对于winform程序来说,当我们点击按钮,需要消耗一定时长才能拿到数据后才能显示在界面上某个控件上的情况,我们通常会专门开一个线程去拿数据,这样不会造成界面处于假死状态 2.常规做法 // ...

  9. C# WinFrom 跨线程访问控件

    1.跨线程访问控件委托和类的定义 using System; using System.Windows.Forms; namespace ahwildlife.Utils { /// <summ ...

随机推荐

  1. js常见的设计模式一

    1.观察者模式 定义一些一对多的关系,将一系列的观察者对目标函数感兴趣,将自己添加进目标函数,当目标函数状态发生改变时,发送通知,以此通知附加在目标上的观察者 /* 目标 */ class subje ...

  2. Houdini:也许是你未曾听过的最振奋人心的 CSS 进化

    原文链接:Houdini: Maybe The Most Exciting Development In CSS You’ve Never Heard Of更多译文将陆续推出,欢迎点赞+收藏+关注我的 ...

  3. Tengine 补充

    Tengine 补充 开机启动 chkconfig --list chkconfig --add nginx chkconfig nginx on 时间问题 service ntpd status 虚 ...

  4. vue简单插件

    已经很久没有学习新的相关知识,对于今后的学习方向可能会集中在vue的源码,render,jsx语法,服务端渲染来学习,巩固好vue的基础和高级的知识,现阶段vue的api和基本用法已经全部掌握,但是还 ...

  5. 前端错误监控上报公共方法,可在父页面及iframe子页面同时使用

    先创建公共文件error-reported.js 内容如下: /** * 获取前端错误信息进行上报 * @param iframe */ function catchError (iframe) { ...

  6. GUI学习之二十四——QDialog学习总结

    今天学习对话框输入控件的基类(QDialog). 一.描述 是对话类窗口(字体框.颜色选择.文件选择框等)的基类. 对话框窗口是顶级窗口(就是说不包含于哪个父类的显示界面里),主要用于短期任务和与用户 ...

  7. [REPRINT]Properties vs. Getters and Setters

    http://www.python-course.eu/python3_properties.php Our new class means breaking the interface. The a ...

  8. Java_环境变量

    介绍 第一步:下载JDK 第二步:搭建环境,双击JDK安装程序 第三步:配置环境变量 第四步:检查JDK安装是否成功 介绍: .java 源文件 我们所编写的代码都在这个文件中 .class 字节码文 ...

  9. table表格 td设置固定宽度

    table宽度自适应,而且部分TD是固定宽度. 只需要将固定宽设死,留下一列不设置宽度,将table宽度设置为100%. table-layout:fixed 作用不是很清楚 <table wi ...

  10. 【微信小程序】基础组件--view text image

    组件的通用属性: id class style hidden bind* catch* data-* view 小程序基础组件,基本等于最常用组件,类似于HTML中的div.view用于构建页面骨架, ...