新线程锁:ManualResetEvent继续等待
ManualResetEvent是一个超时等待的线程锁,如果超时返回false,接收指令显示true,但是没法实现在超时后让他继续等待,这种需求我们可以用在以下场景:
使用异步接收socket数据的数据:
- 1.[主线程]:请求方发送请求,立即创建超时等待线程锁
- 2.[异步线程]:接收数据,数据包合并,数据包合并完成后向解锁主线程
- 3,[主线程]:超时则进入超时异常,接到异步线程的通知则进入后续业务
我们在使用时会发现,第二步可能是一个时间长短很难预估的范围,例如你可能是获取一个数据库(1秒),也可能是获取一个6GB文件(10分钟),他们需要等待的时间是完全不一样。那么主线程的等待时间怎么设置都是不合理的.
我们的需要是:第二步接收一次,就告知主线程一次(我接收了数据,请把等待重置一下吧),很遗憾,ManualResetEvent不具有此功能。
根据这个原理将ManualResetEvent扩展如下即可实现该项模型(VBNet源码,C#可用):
Public Class DCMWait
Dim Wait_1 As New System.Threading.ManualResetEvent(False)
Dim 超时秒 As Integer = 30
Dim 超时Span As TimeSpan
Dim 上一次更新 As Date = "1900-01-01"
Public Delegate Sub d_showstr(str As String)
Private ReadOnly Property 是否有更新 As Boolean
Get
If Now - 上一次更新 > 超时Span Then
Return False
Else
Return True
End If
End Get
End Property
Public Function WaitOne(Optional 超时秒 As Integer = 30, Optional showstr As d_showstr = Nothing) As Boolean
Me.超时秒 = 超时秒
超时Span = TimeSpan.FromSeconds(超时秒)
Wait_1.Reset()
Dim 查询是否更新 = False
Do
Dim rb = Wait_1.WaitOne(超时秒 * 1000)
If rb Then Return True
查询是否更新 = 是否有更新
If 查询是否更新 AndAlso IsNothing(showstr) = False Then showstr("发现更新,继续等待")
Loop While 查询是否更新
Return False
End Function
Public Sub ReWait()
上一次更新 = Now
End Sub
Public Sub [set]()
Wait_1.Set()
End Sub
End Class
上面是完整方法,土豪可以下载调用示例支持一下呗:
https://download.csdn.net/download/meiren777/12419692