首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这是UI线程问题吗?有什么简单的方法可以解决吗?

这是UI线程问题吗?有什么简单的方法可以解决吗?
EN

Stack Overflow用户
提问于 2012-01-23 18:01:48
回答 2查看 121关注 0票数 1

我在和一个USB-HID设备通讯。它将成功地完成数百个发送-接收请求,但偶尔会得到一个空异常错误。

这是线程问题吗?

FormMain.vb:

代码语言:javascript
复制
myHidDevice.transmitPacket(Packet)
myHidDevice.resetEvent.WaitOne(6)
If myHidDevice.rxDataReady = True then
    ' Life is good

MyHidDevicePort.vb

代码语言:javascript
复制
Public Sub DataReceivedHandler(ByVal sender as Object, dataReceived as DataReceivedEventArgs)
    if dataReceived.data Is Nothing Then
        Exit Sub
    Else
        Dim rDataPacket As List(Of Byte) = dataReceived.data.ToList()
        For Each element in rDataPacket
            rxData.dataPacket(i) = element
        rxDataReady = True
        resetEvent.Set()

MySensorClass.vb

代码语言:javascript
复制
Public Overrides Function processPacket(ByRef rxStruct as rStruct, ByVal txPacket()) as Boolean
....
Select Case rxStruct.dataPacket(4)
    Case MOD_DISPLAY_SET_BRIGHTNESS
        rxData(0) = rxStruct.dataPacket(5)
    ...

在rxData.dataPacket(i) =元素处,我会时不时地得到一个NullReference错误。我可以将它包含在try/catch语句中,但如果可能的话,我想修复根问题。

这个设备正在与微控制器通信,可能它们不会总是给出一个值.但我的感觉是,这是某种UI线程问题。在调试时,即使存在空异常,也有很多次dataReceived.data.ToList()中确实存在数据。是否有一种简单的方法可以将整个数据处理例程放在与UI分离的线程上?

编辑:更改了代码以匹配答案,并提供了更多关于其使用位置的信息。在完成对HID设备的大约1,000个发送/接收请求之后,仍然可以获得NullReferenceExceptions。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-24 13:44:55

评论中的对话框太有限了,所以我会尝试用这个作为回答。不幸的是,仍然没有足够的代码给出完整的答案。

一些样本未知数:

什么是rxData (一个custome类,SDK的一部分,一个结构)?

在代码示例i中,rxData.dataPacket(i) = element从何而来,我没有看到它被删除或递增。

为什么表单在等待myHidDevice.resetEvent.WaitOne(6),一旦它认为它是成功的,它会做什么?

processPacket是如何/何时被调用的?

一般来说,我可以推荐的是将对共享状态的访问包装在SyncLock中。在您的例子中,这包括rxData和rxDataReady。

在线程事件回调中,您需要这样做:

代码语言:javascript
复制
SyncLock(syncRoot)
   For Each element in rDataPacket             
      rxData.dataPacket(i) = element
   next         
   rxDataReady = True         
   resetEvent.Set() 
End SyncLock

在等待响应的主表单中,还需要包装对就绪标志的访问:

代码语言:javascript
复制
SyncLock(myHidDevice.syncRoot)
   If myHidDevice.rxDataReady = True then  

      ' do something that consumes the data read in the thread

   End If
End SyncLock

你必须注意你在读和写中保持锁的时间,因为你不能同时做这两件事。

总之,如果您的代码被重构一点以使线程问题更容易处理,我就不会感到惊讶了。如您所建议的那样,阻塞队列/合谋可能是个好主意。只是对您的设计/代码了解不够,无法给出更具体的建议。

票数 1
EN

Stack Overflow用户

发布于 2012-01-23 18:07:22

如果您知道您的对象可能为null,则将其放置在try-catch块中将是处理此情况的不正确方法,因为这将被视为异常编码。相反,在设置对象之前,对其进行空检查。例如:

代码语言:javascript
复制
If Not dataReceived.data Is Nothing Then
   Dim rDataPacket As List(Of Byte) = dataReceived.data.ToList() 
End If

如果您的问题是单个数组元素为null,则还应该在设置/访问它们之前检查它们是否存在。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8976339

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档