ASP源码.NET源码PHP源码JSP源码JAVA源码DELPHI源码PB源码VC源码VB源码Android源码
当前位置:首页 >> 网络编程 >> C#教程 >> c#中Lock(锁)的使用研究以及操作跨线程UI

c#中Lock(锁)的使用研究以及操作跨线程UI

来源:网络整理     时间:2014-11-17     关键词:

本篇文章主要介绍了"c#中Lock(锁)的使用研究以及操作跨线程UI",对于C#教程感兴趣的同学可以参考一下:

本文只针对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#教程有兴趣的朋友有所帮助。

本文网址链接:http://www.codes51.com/article/detail_93940.html

相关图片

相关文章