当前位置:编程学习 > C#/ASP.NET >>

关于串口串口通信读取数据事件的问题~

这个读取事件无法多线程调用否则在等待事件发生那里好象是激活时容易出现锁死的情况 无错误信息提示之前等待时间用的-1无限等待4个自由线程同时执行就100%出现锁死的情况 但改成有限值后锁死情况有所好转6个线程被锁死的概率是30%左右 不知道有没有高人知道根本原因在哪?怎么解决?
<DllImport("kernel32.dll", SetlastError:=True, CharSet:=CharSet.Auto)> Private Shared Function CreateEvent(ByVal lpEventAttributes As IntPtr, ByVal bManualReset As Int32, ByVal bInitialState As Int32, ByVal lpName As String) As IntPtr
    End Function
<DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function SetCommMask(ByVal hFile As IntPtr, ByVal lpEvtMask As Int32) As Int32 '设置通信事件句柄
    End Function
<DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function WaitCommEvent(ByVal hFile As IntPtr, ByRef Mask As EventMasks, ByRef lpOverlap As OVERLAPPED) As Int32 '用来等待通信事件发生。
    End Function
<DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function WaitForSingleObject(ByVal hHandle As IntPtr, ByVal dwMilliseconds As Int32) As Int32 '等待处理事件 不详’ 多线程相关 同步函数
    End Function
         
Private Sub pEventsWatcher()
        '===================================================
        '观察所有事件,直到发送成功 :
        '===================================================
        '//   事件观察  
        Dim lMask As EventMasks = EventMasks.Break Or EventMasks.RxChar Or EventMasks.RXFlag Or EventMasks.StatusError 'EventMasks.Ring,EventMasks.DataSetReady,EventMasks.CarrierDetect,EventMasks.ClearToSend
        Dim aBuf As New ArrayList, tBuf As New ArrayList, iBytesRead, iTotBytes, iErrMask As Int32 '-----New ArrayList动态数组
        Dim uComStat As COMSTAT ', GoOut As Boolean = False
        '-----------------------------------
        '// 创造事件
        muOvlE = New OVERLAPPED
        Dim hOvlE As GCHandle = GCHandle.Alloc(muOvlE, GCHandleType.Pinned)
        muOvlE.hEvent = CreateEvent(Nothing, 1, 0, Nothing)
        If muOvlE.hEvent.ToInt32 = 0 Then Throw New ApplicationException("Error creating event for overlapped reading")
        SetCommMask(mhRS, lMask) '// 设置通信事件句柄
        '// Looks for RxChar--寻找RxChar
        While mbEnableEvents  '通信事件发生时
            WaitCommEvent(mhRS, lMask, muOvlE) '等待通信事件发生
            Select Case WaitForSingleObject(muOvlE.hEvent, 500) 'INFINITE)
                Case WAIT_OBJECT_0
                    '// 事件(或放弃) 被查出
                    If mbEnableEvents = False Then Exit While
                    If (lMask And EventMasks.RxChar) > 0 Then
                        '// Read incoming data
                        ClearCommError(mhRS, iErrMask, uComStat) '清除之前的错误信息 并获得 uComStat.cbInQue
                        If iErrMask = 0 Then
                            Dim ovl As New OVERLAPPED
                            Dim hOvl As GCHandle = GCHandle.Alloc(ovl, GCHandleType.Pinned)
                            ReDim mabtRxBuf(uComStat.cbInQue - 1) '设置要读取出的字节数
                            If ReadFile(mhRS, mabtRxBuf, uComStat.cbInQue, iBytesRead, ovl) > 0 Then '如果读取成功
                                If iBytesRead > 0 Then
                                    GreadIsOK += 1 '判断条件 是否有数据在传送
                                    '// Some bytes read, fills temporary buffer
                                    If iTotBytes < uComStat.cbInQue Then 'miBufThreshold 要读取出的字节数
                                        aBuf.AddRange(mabtRxBuf) '将新的数据放置数组尾部
                                        iTotBytes += iBytesRead
                                    End If
                                    '// Threshold reached?, raises event
                                    If iTotBytes >= uComStat.cbInQue Then '已读出的字节数>=要读取的出的字节数的时候
                                        '//Copies temp buffer into Rx buffer
                                        ReDim mabtRxBuf(iTotBytes - 1)
                                        aBuf.CopyTo(mabtRxBuf) 'CopyTo-已重载。 将 ArrayList 或它的一部分复制到一维数组中。
                                        '==================================================================================收集收到的信息
                                        '==================================================================================
                                        '// Raises event
                                        Try
                                            Me.OnCommEventReceived(Me, lMask) '启动传递事件
                                        Finally
                                            iTotBytes = 0
                                            aBuf.Clear()
                                        End Try
                                    End If
                                End If
                            End If
                            If (hOvl.IsAllocated) Then hOvl.Free()
                        End If
                    Else
                        '// Simply raises OnCommEventHandler event
                        If mbEnableEvents Then Me.OnCommEventReceived(Me, lMask) '启动传递事件
                    End If
                Case WAIT_TIMEOUT '超时
                    ''GoOut = Not GoOut
                    ''If Not GoOut Then Exit While
                Case Else
                    Dim sErr As String = New Win32Exception().Message '得到错误信息
                    Throw New ApplicationException(sErr)
            End Select
        End While
        '// 如果出现异常
        CloseHandle(muOvlE.hEvent) '关闭文件
        muOvlE.hEvent = IntPtr.Zero
        If (hOvlE.IsAllocated) Then hOvlE.Free()
        muOvlE = Nothing
    End Sub
--------------------编程问答-------------------- .net 有 访问窗口的类呀。 你干吗用这个呢。 --------------------编程问答-------------------- 太复杂了 --------------------编程问答-------------------- xuexi
补充:.NET技术 ,  VB.NET
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,