首页 > 代码库 > c#中Lock(锁)的研究以及跨线程UI的操作
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的操作
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。