VB.net - 模块级别的定义如何抛出异常

时间:2018-02-25 18:51:34

标签: vb.net scope

我开始认为自己在VB.net上表现得很好,但是没有这个让我感到难过。

代码看起来像这样

Public Class MyServer
 ..... 
 Public myMQTTclient = New MqttClient("www.myserv.com")
 .....

   Private Sub Ruptela_Server(sender As Object, e As EventArgs) Handles 
     MyBase.Load
       <some code>
       StartMQTT()
       <some more code>
       MQTT_Publish(.....)
     End Sub

Public Function StartMQTT()
   ' Establish a connection 
    Dim code As Byte
    Try
        code = myMQTTclient.Connect(MQTT_ClientID)
    Catch ex As Exception
        <error handling code>
    End Try
    Return code
End Function

Public Sub MQTT_Publish(ByVal DeviceID As String, ByVal Channel As String, ByVal ChannelType As String, ByVal Value As String, ByVal Unit As String)
    Dim myTopic As String = "MyTopic"
    Dim myPayload As String = "My Payload"
    Dim msgId As UShort = myMQTTclient.Publish(myTopic, Encoding.UTF8.GetBytes(myPayload), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, False)
End Sub

现在它可以100%正常工作。编码可能看起来有点奇怪,但意图如下:

a)在模块级别创建一个对象'myMQTTclient',使其在整个模块中具有范围

b)运行StartMQTT() - 它仍然可以看到对象。

c)在主程序调用MQTT_Publish中多次 - 我仍然可以看到对象

现在的问题是这个......一切顺利,直到“www.myserv.com”失败DNS,然后底层的winsock代码抛出异常。

所以...我在想 - 没问题 - 只需将声明包装在try块中,或在启动声明之前检查www.myserv.com是否存在。

啊,但你不能把代码放在模块级别,它必须在子或函数中。

嗯......现在我很难过。必须有一个“正确”的方法来做到这一点,但如果我能弄清楚的话,我会被愚弄。

任何人都可以提供帮助吗?

1 个答案:

答案 0 :(得分:0)

好的,我不确定我是否拥有合适的库。但是我找到了这个Nuget包:OpenNETCF.MQTT,它似乎有你正在使用的类。

我会这样做

Public Class MyServerClass
    Implements IDisposable

    Public myMQTTclient As MQTTClient

    'Private Sub Ruptela_Server(sender As Object, e As EventArgs) Handles MyBase.Load
    '    ' <some code>
    '    StartMQTT()
    '    ' <some more code>
    '    ' MQTT_Publish(.....)
    'End Sub

    Public Sub New(brokerHostName As String)
        myMQTTclient = New MQTTClient(brokerHostName)
    End Sub

    Public Function StartMQTT()
        ' Establish a connection 
        Dim code As Byte
        Try
            code = myMQTTclient.Connect(MQTT_ClientID)
        Catch ex As Exception
            '<error handling code>
        End Try
        Return code
    End Function

    Public Sub MQTT_Publish(ByVal DeviceID As String, ByVal Channel As String, ByVal ChannelType As String, ByVal Value As String, ByVal Unit As String)
        Dim myTopic As String = "MyTopic"
        Dim myPayload As String = "My Payload"
        Dim msgId As UShort = myMQTTclient.Publish(myTopic, Encoding.UTF8.GetBytes(myPayload), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, False)
    End Sub

#Region "IDisposable Support"
    Private disposedValue As Boolean

    Protected Overridable Sub Dispose(disposing As Boolean)
        If Not disposedValue Then
            If disposing Then
                myMQTTclient.Dispose()
            End If
        End If
        disposedValue = True
    End Sub

    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
    End Sub
#End Region

End Class

现在,您可以在Using块中看到实施IDisposable时的用法:

Module Module1

    Sub Main()
        Using myserver As New MyServerClass("www.myserv.com")
            myserver.StartMQTT()
            myserver.MQTT_Publish(...)
        End Using
    End Sub

End Module

这使得你的对象只在Using中的范围内,并且对象的Dispose方法将自动在End Using上调用

我不知道基类最初是什么以及为什么声明Private Sub Ruptela_Server(sender As Object, e As EventArgs) Handles MyBase.Load。好像它可能是一种形式?如果是这种情况,您应该将服务器代码与表单代码分开。我想你可以将Using粘贴到表单加载中,但是你会阻止你的UI线程。引用的库具有Async支持,因此如果来自UI,可能最好利用它。

我做了很多假设,所以我会停下来让你发表评论,看看我的答案有多接近。