C#中使用ManualResetEvent (阻塞->激活->阻塞->激活.......)

在用C#写一个程序时偶然碰到了一个问题,最开始我的程序是使用两个线程进行的,其中一个线程完成两个任务,一边不停地接收数据,一边通将接收到的数据发送出去。这两个任务是放在一个循环中的,即收一个发送一个,边收边发。发现一个问题,如果发送时被阻塞,整个线程都将被阻塞,势必将影响到正常地接收数据。于是想将这两个任务分别放到两个不同的线程中。这样,就引入了两个线程同步的问题。、
C#提供lock方法,天经地义地,想到同步就应该想到锁。但是仔细想想却又带来一个问题,如果发送线程被阻塞,不会释放锁,同样将阻塞接收线程。仔细想想,这两个线程其实地位是不一样的。一为主,一为次。次线程是必须依赖于主线程的。没有主线程接收到的数据,次线程也不能发送数据出去,类似于Producer-Consumer问题。对于这种不平等的情况,用锁是不恰当的。在Posix的系统当中,我们可以用semaphore来解决这个问题的。那么在C#中我们该怎么办呢?
ManualResetEvent,三个方法:
WaitOne(),阻塞等待有线程设置该信号;
Set(),设置信号,通知阻塞线程不用阻塞了;
Reset(),重设信号,WaitOne有要被阻塞了。
所以,我最后采取了如下策略。

用false初始化一个ManualResetEvent实例,false意味着调用WaitOne的线程将被阻塞至Set后。

   接收线程 (Producer)
   loop {
      接收数据;
      Set();           //设置信号
   }

   发送线程 (Consumer)
   loop {
       WaitOne(); //等待信号被set
       发送数据;
       Reset();     //自己阻塞自己
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值