Winform 让跨线程访问变得更简单
Winform 让跨线程访问变得更简单
前言
由于多线程可能导致对控件访问的不一致,导致出现问题。C#中默认是要线程安全的,即在访问控件时需要首先判断是否跨线程,如果是跨线程的直接访问,在运行时会抛出异常。近期在项目中碰到这个问题,首先想到的是,关闭跨线程检查,因为做的Winform没有多么复杂,图省事就直接这样做了,之后又出了一点点问题,还是必需通过委托的方式来实现。
资源下载
解决跨线程访问:
网上的资料很多,这里直接摘抄。
1、关闭跨线程检查。
2、通过委托的方式,在控件的线程上执行。
具体的代码如下:

using System;
using System.Threading;
using System.Windows.Forms; namespace WindowsFormsApplication1
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
//方法一:不进行跨线程安全检查
CheckForIllegalCrossThreadCalls = false;
} private void button1_Click(object sender, EventArgs e)
{
Thread th1 = new Thread(new ThreadStart(CalNum));
th1.Start();
} private void CalNum()
{
SetCalResult(DateTime.Now.Second);
} //方法二:检查是否跨线程,然后将方法加入委托,调用委托
public delegate void SetTextHandler(int result);
private void SetCalResult(int result)
{
if (label2.InvokeRequired == true)
{
SetTextHandler set = new SetTextHandler(SetCalResult);//委托的方法参数应和SetCalResult一致
label2.Invoke(set, new object[] { result }); //此方法第二参数用于传入方法,代替形参result
}
else
{
label2.Text = result.ToString();
}
}
}
}

改进
在我的Winform程序中,子线程涉及到对多个控件的更改,于是封装了一下,我这里使用的是拓展方法,只有在.net 3.5上才能支持,如果是.net2.0的环境,需要添加
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]
public class ExtensionAttribute : Attribute { }
}
封装如下:

using System.Threading;
using System.Windows.Forms; namespace WindowsFormsApplication1
{
public static class Class1
{
/// <summary>
/// 跨线程访问控件 在控件上执行委托
/// </summary>
/// <param name="ctl">控件</param>
/// <param name="del">执行的委托</param>
public static void CrossThreadCalls(this Control ctl, ThreadStart del)
{
if (del == null) return;
if (ctl.InvokeRequired)
ctl.Invoke(del, null);
else
del();
}
}
}

具体的测试如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Windows.Forms; namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void button1_Click(object sender, EventArgs e)
{
var th = new Thread(() =>
{
//label1.Enabled = false;
label1.CrossThreadCalls(() => { label1.Enabled = !label1.Enabled; });
WriteMessage(DateTime.Now.ToString());
});
th.IsBackground = true;
th.Start();
} public void WriteMessage(string msg)
{
label1.CrossThreadCalls(() =>
{
label1.Text = msg;
});
}
}
}

这样一行代码就可以完成跨线程访问啦。

Winform 让跨线程访问变得更简单的更多相关文章
- Winform之跨线程访问控件(在进度条上显示字体)
此文章对于遇到必须使用线程但是没有办法在线程内操作控件的问题的处理 有很好的解决方案(个人认为的.有更好的方案欢迎交流.) 在做跨线程访问之前我们先了解下我们所做的需要达到的效果: 这个是批量的将x ...
- 实现 winform 异步跨线程访问UI控件
在开发winform时经常会用到多线程防止界面出现假死现象,比如当你单击某个按钮时,需要执行很多代码,但是在执行过程中想实时的将当前执行的情况报告给用户,类型进度条或文本什么的. 这个时候很显然,如果 ...
- 理解SynchronizationContext,如何在Winform里面跨线程访问UI控件
SynchronizationContext 类是一个基类,可提供不带同步的自由线程上下文. 此类实现的同步模型的目的是使公共语言运行库内部的异步/同步操作能够针对不同的异步模型采取正确的行为.此模型 ...
- C#WinForm解决跨线程访问控件属性报错
方式一(在程序初始化构造函数中加一行代码): public Form1() { InitializeComponent(); Control.CheckForIllegalCrossThreadCal ...
- winform 跨线程访问问题
一.问题描述 进行winform 开发我们在进行数据交换时避免不了使用多线程或异步方法,这样操作也将避免不了跨线程对控件进行操作(赋值.修改属性). 下面通过一个测试说明一下问题 点击一个按钮异步对t ...
- winform跨线程访问控件
首先说下,.net 2.0以后加强了安全机制,不允许在winform中直接跨线程访问控件的属性.所以除了控件所在的线程外的线程调用会抛异常 (Cross-thread operation not va ...
- 如何跨线程访问Winform中的UI元素
如何跨线程访问Winform中的UI元素 假如制作一个Socket聊天应用程序,很可能会用到多线程: 例如为Receive方法开辟单独一个线程,例如为Receive方法开辟单独一个线程(后台运行的线程 ...
- WPF 中那些可跨线程访问的 DispatcherObject(WPF Free Threaded Dispatcher Object)
原文 WPF 中那些可跨线程访问的 DispatcherObject(WPF Free Threaded Dispatcher Object) 众所周知的,WPF 中多数对象都继承自 Dispatch ...
- C# WinFrom 跨线程访问控件
1.跨线程访问控件委托和类的定义 using System; using System.Windows.Forms; namespace ahwildlife.Utils { /// <summ ...
随机推荐
- asp.net 给按钮 增加事件
一个页面,有查询,审核,删除,取消审核 按钮,每次结尾 处都要 调用 Initdata方法,重新刷新数据 繁琐哇,我的解决方法是 protected void Page_Load(object sen ...
- 什么是MEAN全堆栈javascript开发框架
什么是MEAN全堆栈javascript开发框架 使用JavaScript能够完整迅速做出Web应用程序,目前一套工具包括MongoDB.ExpressJS,AngularJS和Node.js越来越受 ...
- JS操作cookie的实例
<script type="text/javascript"> //写cookies函数 function SetCookie(name, value)//两个参数,一 ...
- 设计模式---订阅发布模式(Subscribe/Publish)
设计模式---订阅发布模式(Subscribe/Publish) 订阅发布模式定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象.这个主题对象在自身状态变化时,会通知所有订阅者对象,使 ...
- 【hoj】2651 pie 二分查找
二分查找是一个非常主要的算法,针对的是有序的数列,通过中间值的大小来推断接下来查找的是左半段还是右半段,直到中间值的大小等于要找到的数时或者中间值满足一定的条件就返回,所以当有些问题要求在一定范围内找 ...
- 常见ActiveX控件下载大全
ActiveX是微软对于一系列策略性面向对象程序技术和工具的称呼,ActiveX控件可以在Windows窗体和Web程序上使用,所以不管是什么语 言开发的应用程序只要在windows窗体和html页面 ...
- 使用Visual Source Safe 2005 - 初学者系列 - 学习者系列文章
本文介绍微软的Visual Source Safe 2005工具的使用 1. 打开该软件,选择“新建数据库” 2. 显示欢迎页 3.选择路径.这里是服务器上代码存放的目录. 4.这里选择第一项 5 ...
- Sql Server 主键由字母数字组成并按照数字自动增长
在SQL SERVER 中如果我们想要使主键按照一定规则自动增长我们可以这样做: 这里我们新建一张研究表,里面有研究ID,研究人员姓名和研究医院. 我们使SicentificId 设为主键 并且从1开 ...
- Oracle汇总笔记
http://gzf_PC:1158/em数据库配置文件已经安装到 D:\WorkC,同时其他选定的安装组件也已经安装到 D:\WorkC\oracle.iSQL*Plus URL 为:http:// ...
- Visual Studio 当前不会命中断点的问题
这个问题一般有两个版本 1.当前不会命中断点,还没有为该文档加载任何符号. 2.当前不会命中断点,源代码与原始版本不同. 要解决第一个问题,就要了解一种文件格式“PDB(Program DataBas ...