c#中Lock(锁)的研究以及跨线程UI的操作
- 本文只针对C#中,多线程同步所用到的锁(lock)作为研究对象。由于想更直观的显示结果,所以,在做demo的时候,就把多线程通过事件操作UI的代码也写了出来,留作备忘和分享吧。
其实多线程的同步,使用同步锁的方法用了好多次,今天无意中看到MSDN中,建议用:1 private static readonly object locker1 = new object();2 private readonly object locker2 = new object();备注:原文并没有加readonly,是我后来自己加进去的。我不仅思考了一下他们的区别。然后我写了一段代码进行测试,测试类代码如下:复制代码/// <summary>/// 跨线程操作UI的时候传递的参数,本文为了显示消息,所以简单的封装了一个/// </summary>public class MyEventArgs : EventArgs{public readonly string Message = string.Empty;public MyEventArgs(string msg){this.Message = msg;}}/// <summary>/// 测试类,用于测试2种锁的区别/// </summary>public class LockTest{//2个锁private static readonly object Locker1 = new object();private readonly object Locker2 = new object();/// <summary>/// 跨线程操作UI的委托和事件/// </summary>public delegate void MessageEventHandler(object sender, MyEventArgs e);public event MessageEventHandler MessageEvent;public void OnMessage(MyEventArgs e){if (this.MessageEvent != null) MessageEvent(this, e);}//要锁的变量,通过它可以看出2种锁在不同情况下的效果private int num = 0;//实例名字private readonly string Name;public LockTest(string name){Name = name;}//第一种锁执行的方法public void AddNum1(){lock (Locker1){num = 0;ShowMessage();}}//第二种锁执行的方法public void AddNum2(){lock (Locker2){num = 0;ShowMessage();}}//锁内的一些操作,并通过事件,把关键的消息显示到主线程中的UI里private void ShowMessage(){string msg = "";for (int i = 0; i < 10; i++){num += 1;msg = string.Format("线程 [{0}],实例[{1}]中num的值是[{2}]", Thread.CurrentThread.Name, this.Name, num);OnMessage(new MyEventArgs(msg));Thread.Sleep(100);}msg = string.Format("======线程 [{0}]执行完毕======", Thread.CurrentThread.Name);OnMessage(new MyEventArgs(msg));}}复制代码测试用的类写完了,开始测试:首先测试单个实例、多线程,2种锁的区别:private void button1_Click(object sender, EventArgs e){LockTest test = new LockTest("LockTest 1");test.MessageEvent += new LockTest.MessageEventHandler(MessageCallBack);listBox1.Items.Clear();for (int i = 0; i <= 2; i++){Thread a = new Thread(new ThreadStart(test.AddNum1));a.Name = i.ToString();a.Start();}}private void button2_Click(object sender, EventArgs e){LockTest test = new LockTest("LockTest 1");test.MessageEvent += new LockTest.MessageEventHandler(MessageCallBack);listBox1.Items.Clear();for (int i = 0; i <= 2; i++){Thread a = new Thread(new ThreadStart(test.AddNum2));a.Name = i.ToString();a.Start();}}输出结果一模一样:得出结论:如果对一个实例,多线程访问的时候,2种锁是没有区别的。下面是测试多个实例的情况(静态锁):复制代码private void button3_Click(object sender, EventArgs e){listBox1.Items.Clear();for (int i = 0; i <= 2; i++){LockTest test = new LockTest("LockTest " + i.ToString());test.MessageEvent += new LockTest.MessageEventHandler(MessageCallBack);Thread a = new Thread(new ThreadStart(test.AddNum1));a.Name = i.ToString();a.Start();}}复制代码得到结果:得出结论,在静态锁面前,线程依旧要排队,虽然不是一个实例,但是锁是唯一的,线程只认锁,所以线程并没有并发!继续测试(非静态的锁):复制代码private void button4_Click(object sender, EventArgs e){listBox1.Items.Clear();for (int i = 0; i <= 2; i++){LockTest test = new LockTest("LockTest " + i.ToString());test.MessageEvent += new LockTest.MessageEventHandler(MessageCallBack);Thread a = new Thread(new ThreadStart(test.AddNum2));a.Name = i.ToString();a.Start();}}复制代码得到的结果:得出结论:非静态锁的时候,多线程并发了,一起在工作。其实,测试的结果之前也能猜想出来,只不过,不测试下,心里总是觉得没底,呵呵,测试完了,也就彻底释然了!窗体中,用于事件回调,显示到UI里的代码在这里:复制代码delegate void MessageHandler(string msg);public void MessageCallBack(object sender, MyEventArgs e){MessageHandler handler = new MessageHandler(ShowMessage);this.Invoke(handler, new object[] { e.Message });}public void ShowMessage(string msg){this.listBox1.Items.Add(msg);}
c#中Lock(锁)的研究以及跨线程UI的操作的更多相关文章
- c#中多线程同步Lock(锁)的研究以及跨线程UI的操作
本文只针对C#中,多线程同步所用到的锁(lock)作为研究对象.由于想更直观的显示结果,所以,在做demo的时候,就把多线程通过事件操作UI的代码也写了出来,留作备忘和分享吧. 其实多线程的同步,使用 ...
- c#中多线程同步Lock(锁)的研究以及跨线程UI的操作 (转)
https://www.cnblogs.com/tommyheng/p/4104552.html 本文只针对C#中,多线程同步所用到的锁(lock)作为研究对象.由于想更直观的显示结果,所以,在做de ...
- [WinForm]WinForm跨线程UI操作常用控件类大全
前言 在C#开发的WinForm窗体程序开发的时候,经常会使用多线程处理一些比较耗时之类的操作.不过会有一个问题:就是涉及到跨线程操作UI元素. 相信才开始接触的人一定会遇上这个问题. 为了解决这个问 ...
- 通过ReentrantLock简单了解下并发包中的锁
ReentrantLock在进行实例化时,可以通过构造函数的参数选择是否使用公平锁FairSync或者非公平锁NonfairSync,两者的区别比较简单,如果是公平锁则新来的线程会先检测同步队列中是否 ...
- 在.Net中进行跨线程的控件操作(上篇:Control.Invoke)
本文的重点在于介绍如何在多线程编程中,从非UI线程上访问界面中的控件.有过多线程编程经验的人都知道,当我们在非UI线程上试图给一个界面中的控件赋值的时候,比如说label的Text属性,系统会抛出一个 ...
- WPF 中那些可跨线程访问的 DispatcherObject(WPF Free Threaded Dispatcher Object)
原文 WPF 中那些可跨线程访问的 DispatcherObject(WPF Free Threaded Dispatcher Object) 众所周知的,WPF 中多数对象都继承自 Dispatch ...
- 『动善时』JMeter基础 — 38、JMeter中实现跨线程组关联
目录 1.JMeter中实现跨线程组关联说明 (1)JMeter中实现跨线程组关联步骤 (2)测试计划内包含的元件 2.用户登陆请求的相关操作 (1)进行登陆操作获取Cookie信息 (2)把Cook ...
- Winfrom 如何安全简单的跨线程更新控件
来源:http://www.cnblogs.com/rainbowzc/archive/2010/09/29/1838788.html 由于多线程可能导致对控件访问的不一致,导致出现问题.C#中默认是 ...
- MySql InnoDB中的锁研究
# MySql InnoDB中的锁研究 ## 1.InnoDB中有哪些锁### 1. 共享和排他(独占)锁(Shared and Exclusive Locks) InnoDB实现标准的行级锁定,其中 ...
随机推荐
- (转)传统MySQL+ Memcached架构遇到的问题
实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题: ...
- dorado抽取js
dorado创建的视图文件如果有控件拥有事件的话,那么它是可以抽取js的, 右键视图->抽取JavaScript 然后就会出现一个同名的.js文件 (注意,所有的属性需要有id,因为js需要绑定 ...
- jquery 动态添加下拉框 需要增加 煊染 selectmenu("refresh");
若通过js动态选择下拉框的值必须刷新下拉框,例如:var selArray = $("select#sel");selArray[0].selectedIndex = 1;selA ...
- msSQL数据库备份还原小结
MSSQL自带了一个样例数据库pubs,就拿这个举例好了. 首先,来一次完全备份.对于数据量很大的数据库,这样的操作当然很费时间.所以我们采用每天凌晨4点一次完全备份,每个小时一个差异备份,每分钟一次 ...
- lamp 中基本配置常识
// apache// 禁止访问目录// 开启 url重写// 重写定义错误页面// 日志分页// 增加并发连接数// 设置连接连接的时间 // threadsPerChild // 每个进程的线程数 ...
- SQL索引问题
很多文章都提到使用IN,OR会破坏索引,造成全表扫描,但实际测试却不是这样. ) 或者 ,) 以上SQL文,第一组(=,IN),第二组(=,OR,IN),每一组的两个SQL文都使用相同的执行计划,执行 ...
- memcached全面剖析--4
memcached的分布式算法 memcached的分布式 正如第1次中介绍的那样, memcached虽然称为“分布式”缓存服务器,但服务器端并没有“分布式”功能. 服务器端仅包括 第2次. 第 ...
- PYTHON代码摘录
文件处理 #典型的读取文件代码 row_data = {} with open('PaceData.csv') as paces: column_heading = paces.readline(). ...
- 【BZOJ】1046 : [HAOI2007]上升序列
1046: [HAOI2007]上升序列 题意:给定S={a1,a2,a3,…,an}问是否存在P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm)且 ...
- 用原生JavaScript实现图片瀑布流的浏览效果
学习JS,活跃思维,灵活运用的一个较为典型的学习案例.同一个瀑布流的效果但实现方式却很多,利用递归.冒泡等等手法都可以达到你想要的目的.这次要说的就是利用类似递归来实现此效果的原创方案.此方案个人认为 ...