博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
定时器与锁
阅读量:4676 次
发布时间:2019-06-09

本文共 3228 字,大约阅读时间需要 10 分钟。

8.1定时器

若要长期定时进行一些工作,比如像邮箱更新,实时收听信息等等,可以利用定时器Timer进行操作。

在System.Threading命名空间中存在Timer类与对应的TimerCallback委托,它可以在后台线程中执行一些长期的定时操作,使主线程不受干扰。
Timer类中最常用的构造函数为 public Timer( timerCallback , object , int , int )
timerCallback委托可以绑定执行方法,执行方法必须返回void,它可以是无参数方法,也可以带一个object参数的方法。
第二个参数是为 timerCallback 委托输入的参数对象。
第三个参数是开始执行前等待的时间。
第四个参数是每次执行之间的等待时间。

开发实例

1     class Program  2     {
3 static void Main(string[] args) 4 {
5 ThreadPool.SetMaxThreads(1000, 1000); 6 7 TimerCallback callback = new TimerCallback(ThreadPoolMessage); 8 Timer t = new Timer(callback,"Hello Jack! ", 0, 1000); 9 Console.ReadKey(); 10 } 11 12 //显示线程池现状 13 static void ThreadPoolMessage(object data) 14 {
15 int a, b; 16 ThreadPool.GetAvailableThreads(out a, out b); 17 string message = string.Format("{0}\n CurrentThreadId is:{1}\n" + 18 " CurrentThread IsBackground:{2}\n" + 19 " WorkerThreads is:{3}\n CompletionPortThreads is:{4}\n", 20 data + "Time now is " + DateTime.Now.ToLongTimeString(), 21 Thread.CurrentThread.ManagedThreadId, 22 Thread.CurrentThread.IsBackground.ToString(), 23 a.ToString(), b.ToString()); 24 Console.WriteLine(message); 25 } 26 }

注意观察运行结果,每次调用Timer绑定的方法时不一定是使用同一线程,但线程都会是来自工作者线程的后台线程。

8.2 锁

在使用多线程开发时,存在一定的共用数据,为了避免多线程同时操作同一数据,.NET提供了lock、Monitor、Interlocked等多个锁定数据的方式。

8.2.1 lock

lock的使用比较简单,如果需要锁定某个对象时,可以直接使用lock(this)的方式。

1 private void Method() 2 {
3 lock(this) 4 {
5 //在此进行的操作能保证在同一时间内只有一个线程对此对象操作 6 } 7 }

如果操作只锁定某段代码,可以事先建立一个object对象,并对此对象进行操作锁定,这也是.net提倡的锁定用法。

1 class Control  2 {
3 private object obj=new object(); 4 5 public void Method() 6 {
7 lock(obj) 8 {.......} 9 } 10 }

 

8.2.2 Montior

Montior存在于System.Thread命名空间内,相比lock,Montior使用更灵活。

它存在 Enter, Exit 两个方法,它可以对对象进行锁定与解锁,比lock使用更灵活。

1 class Control  2 {
3 private object obj=new object(); 4 5 public void Method() 6 {
7 Monitor.Enter(obj); 8 try 9 {......} 10 catch(Excetion ex) 11 {......} 12 finally 13 {
14 Monitor.Exit(obj); 15 } 16 } 17 } 18

使用try的方式,能确保程序不会因死锁而释放出异常!

而且在finally中释放obj对象能够确保无论是否出现死锁状态,系统都会释放obj对象。
而且Monitor中还存在Wait方法可以让线程等待一段时间,然后在完成时使用Pulse、PulseAll等方法通知等待线程。

 

8.2.3 Interlocked

Interlocked存在于System.Thread命名空间内,它的操作比Monitor使用更简单。

它存在CompareExchange、Decrement、Exchange、Increment等常用方法让参数在安全的情况进行数据交换。

Increment、Decrement 可以使参数安全地加1或减1并返回递增后的新值。

1 class Example 2 {
3 private int a=1; 4 5 public void AddOne() 6 {
7 int newA=Interlocked.Increment(ref a); 8 } 9 }

Exchange可以安全地变量赋值。

1 public void SetData() 2 {
3 Interlocked.Exchange(ref a,100); 4 }

CompareExchange使用特别方便,它相当于if的用法,当a等于1时,则把100赋值给a。

1 public void CompareAndExchange() 2 {
3 Interlocked.CompareExchange(ref a,100,1); 4 }

转载于:https://www.cnblogs.com/meilibao/archive/2012/10/16/2725748.html

你可能感兴趣的文章
实验吧-密码学-我喜欢培根
查看>>
java set集合与List集合练习
查看>>
简短总结一下C#里跨线程更新UI
查看>>
201612-2 工资计算
查看>>
DevExpress下拉多选框 CheckComboboxEdit、CheckedListBoxControl
查看>>
MySQL 忘记Root密码
查看>>
WPF后台自定义文字带背景的选择状态按钮
查看>>
【转自Mgen】 .NET(C#):谈谈各种结束进程的方法
查看>>
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
查看>>
用原生javascript做的一个打地鼠的小游戏
查看>>
小米手机 - Charles无法安装证书 因为无法读取证书
查看>>
android 动态壁纸开发
查看>>
你误解了Windows的文件后缀名吗?
查看>>
谷歌浏览器插件
查看>>
gcc malloc/free的质疑
查看>>
Servlet注解
查看>>
今后几个月的IT读书计划
查看>>
蓝桥杯 传球游戏 动态规划
查看>>
apk反编译、smali修改、回编译笔记
查看>>
.Net程序员学习Linux最简单的方法(转载)
查看>>