zeromq / netmq

A 100% native C# implementation of ZeroMQ for .NET
Other
2.95k stars 744 forks source link

I got an unhandled exception (NetMQ.FaultException) #394

Closed ghost closed 9 years ago

ghost commented 9 years ago

Sorry Sir, My English is very bad, I only can speak Chinese, so I use Google Translate.

I got an unhandled exception, my application crash.

exception message: Cannot close an uninitialised Msg.

The follow is my stack trace: Application: MySports.exe Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: NetMQ.FaultException Stack: at NetMQ.Msg.Close() at NetMQ.Core.Transports.V2Encoder.MessageReady() at NetMQ.Core.Transports.V2Encoder.Next() at NetMQ.Core.Transports.EncoderBase.GetData(NetMQ.Core.Transports.ByteArraySegment ByRef, Int32 ByRef, Int32 ByRef) at NetMQ.Core.Transports.StreamEngine.BeginSending() at NetMQ.Core.Transports.StreamEngine.Handle(Action, System.Net.Sockets.SocketError, Int32) at NetMQ.Core.Transports.StreamEngine.FeedAction(Action, System.Net.Sockets.SocketError, Int32) at NetMQ.Core.Transports.StreamEngine.ActivateOut() at NetMQ.Core.SessionBase.ReadActivated(NetMQ.Core.Pipe) at NetMQ.Core.Pipe.ProcessActivateRead() at NetMQ.Core.ZObject.ProcessCommand(NetMQ.Core.Command) at NetMQ.Core.IOThread.Ready() at NetMQ.Core.Utils.Proactor.Loop() at System.Threading.ThreadHelper.ThreadStart_Context(System.Object) at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) at System.Threading.ThreadHelper.ThreadStart()

Here is my code: Imports MySports.Bbmdj Imports Singmar.N Imports KingLeader.Data Imports NetMQ

Namespace MySports.Bbmdj Public Class ClientObject Dim readLogger As NLog.Logger = NLog.LogManager.GetLogger("ClientObjectRead")

    Dim writeLogger As NLog.Logger = NLog.LogManager.GetLogger("ClientObjectWrite")

    Dim connectLogger As NLog.Logger = NLog.LogManager.GetLogger("ClientObjectConnect")

    Dim exceptionLogger As NLog.Logger = NLog.LogManager.GetLogger("ClientObjectException")

    Private app As App = app.getInstance()

    Private clientThread As System.Threading.Thread                 

    Private pushContext As NetMQ.NetMQContext = Nothing

    Private pushClient As NetMQ.Sockets.PushSocket = Nothing        

    Private serverIp As String = ""

    Private pageDataList As List(Of PageData)

    Public Sub New()
        Me.pageDataList = New List(Of PageData)()            
        Me.serverIp = app.serverIP                        
        Me.clientThread = New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf clientThreadImplement))
        Me.clientThread.IsBackground = True
        Me.clientThread.Start()                
        Try
            Me.initializePushClient()
        Catch ex As Exception

        End Try            
        Me.maintainThread = New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf maintainThreadImplement))
        Me.maintainThread.IsBackground = True
        Me.maintainThread.Start()
        '            
    End Sub          

    Sub clientThreadImplement()            
        While (True)
            Try
                Using context As NetMQ.NetMQContext = NetMQ.NetMQContext.Create()
                    Using subscriberClient As NetMQ.Sockets.SubscriberSocket = context.CreateSubscriberSocket()
                        subscriberClient.Connect(String.Format("tcp://{0}:8153", Me.serverIp))
                        subscriberClient.Subscribe("")
                        connectLogger.Info("Connection establish")
                        While True
                            Dim str As String = subscriberClient.ReceiveFrameString()
                            Dim data As ExchangeData = deserialize(str)
                            If (data IsNot Nothing) Then
                                If (data.Command = ExchangeCommand.PageData) Then
                                    'something to do
                                End If
                            End If
                        End While
                    End Using
                End Using
            Catch ex1 As Exception
                exceptionLogger.Warn(ex1, "{0}", "ReadObjectException")
            End Try
            System.Threading.Thread.Sleep(2000)
        End While            
    End Sub        

    Public Sub WriteObject(data As ExchangeData)
        Try
            Dim pd As PageData = DirectCast(data.Data, PageData)
            pd.SiteName = pd.SiteName.RegexReplace("-\d{1,2}$", "")
            If (data.Command = ExchangeCommand.PageData) Then
                'something to do
            End If
            If (app.IsShareHtml) Then                                                       
                Me.pushClient.SendFrame(serialize(pd.SiteName, pd.GameType, data))                                  
            End If
        Catch ex1 As Exception
            Try
                Me.initializePushClient()
            Catch ex2 As Exception

            End Try
            Try
                exceptionLogger.Warn(ex1, "{0}", "WriteObjectException")
            Catch ex2 As Exception

            End Try
        End Try
    End Sub        

    Private Function serialize(siteName As String, gameType As String, data As ExchangeData) As String
        Dim returnValue = String.Empty
        returnValue = String.Format("{0}|{1}|{2}|{3}|{4}", siteName, gameType, "Username", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), Singmar.IO.Serializer.Compress(Singmar.IO.Serializer.SerializeToByteArray(data), Ionic.Zlib.CompressionLevel.BestCompression).ToBase64String())
        Return returnValue
    End Function

    Private Function deserialize(data As String) As ExchangeData
        Dim returnValue As ExchangeData = Nothing
        Dim strArray() As String = data.Split("|", StringSplitOptions.RemoveEmptyEntries)
        If (strArray.Length = 5) Then
            Try
                returnValue = DirectCast(Singmar.IO.Serializer.DeserializeFromByteArray(Singmar.IO.Serializer.Decompress(strArray(4).FromBase64String())), ExchangeData)
            Catch ex As Exception

            End Try
        End If
        Return returnValue
    End Function

    Private Sub initializePushClient()
        Me.pushContext = NetMQ.NetMQContext.Create()
        Me.pushClient = Me.pushContext.CreatePushSocket()
        Me.pushClient.Connect(String.Format("tcp://{0}:8152", Me.serverIp))
    End Sub
End Class

End Namespace

I guess my unhandled exception line is Dim str As String = subscriberClient.ReceiveFrameString() or Me.pushClient.SendFrame(serialize(pd.SiteName, pd.GameType, data))
, and NetMQ inner thread throws exception from Msg struct Close() method, This exception is a period of time before they occur, how do I solve this exception ?? please, thx.

somdoron commented 9 years ago

Which version are you using?

On Sun, Oct 25, 2015 at 10:59 AM, Yojinlin notifications@github.com wrote:

Sorry Sir, My English is very bad, I only can speak Chinese, so I use Google Translate.

I got an unhandled exception, my application crash.

exception message: Cannot close an uninitialised Msg.

The follow is my stack trace: Application: MySports.exe Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: NetMQ.FaultException Stack: at NetMQ.Msg.Close() at NetMQ.Core.Transports.V2Encoder.MessageReady() at NetMQ.Core.Transports.V2Encoder.Next() at NetMQ.Core.Transports.EncoderBase.GetData(NetMQ.Core.Transports.ByteArraySegment ByRef, Int32 ByRef, Int32 ByRef) at NetMQ.Core.Transports.StreamEngine.BeginSending() at NetMQ.Core.Transports.StreamEngine.Handle(Action, System.Net.Sockets.SocketError, Int32) at NetMQ.Core.Transports.StreamEngine.FeedAction(Action, System.Net.Sockets.SocketError, Int32) at NetMQ.Core.Transports.StreamEngine.ActivateOut() at NetMQ.Core.SessionBase.ReadActivated(NetMQ.Core.Pipe) at NetMQ.Core.Pipe.ProcessActivateRead() at NetMQ.Core.ZObject.ProcessCommand(NetMQ.Core.Command) at NetMQ.Core.IOThread.Ready() at NetMQ.Core.Utils.Proactor.Loop() at System.Threading.ThreadHelper.ThreadStart_Context(System.Object) at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) at System.Threading.ThreadHelper.ThreadStart()

Here is my code: Imports MySports.Bbmdj Imports Singmar.N Imports KingLeader.Data Imports NetMQ

Namespace MySports.Bbmdj Public Class ClientObject Dim readLogger As NLog.Logger = NLog.LogManager.GetLogger("ClientObjectRead")

Dim writeLogger As NLog.Logger = NLog.LogManager.GetLogger("ClientObjectWrite")

Dim connectLogger As NLog.Logger = NLog.LogManager.GetLogger("ClientObjectConnect")

Dim exceptionLogger As NLog.Logger = NLog.LogManager.GetLogger("ClientObjectException")

Private app As App = app.getInstance()

Private clientThread As System.Threading.Thread

Private pushContext As NetMQ.NetMQContext = Nothing

Private pushClient As NetMQ.Sockets.PushSocket = Nothing

Private serverIp As String = ""

Private pageDataList As List(Of PageData)

Public Sub New()
    Me.pageDataList = New List(Of PageData)()
    Me.serverIp = app.serverIP
    Me.clientThread = New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf clientThreadImplement))
    Me.clientThread.IsBackground = True
    Me.clientThread.Start()
    Try
        Me.initializePushClient()
    Catch ex As Exception

    End Try
    Me.maintainThread = New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf maintainThreadImplement))
    Me.maintainThread.IsBackground = True
    Me.maintainThread.Start()
    '
End Sub

Sub clientThreadImplement()
    While (True)
        Try
            Using context As NetMQ.NetMQContext = NetMQ.NetMQContext.Create()
                Using subscriberClient As NetMQ.Sockets.SubscriberSocket = context.CreateSubscriberSocket()
                    subscriberClient.Connect(String.Format("tcp://{0}:8153", Me.serverIp))
                    subscriberClient.Subscribe("")
                    connectLogger.Info("Connection establish")
                    While True
                        Dim str As String = subscriberClient.ReceiveFrameString()
                        Dim data As ExchangeData = deserialize(str)
                        If (data IsNot Nothing) Then
                            If (data.Command = ExchangeCommand.PageData) Then
                                'something to do
                            End If
                        End If
                    End While
                End Using
            End Using
        Catch ex1 As Exception
            exceptionLogger.Warn(ex1, "{0}", "ReadObjectException")
        End Try
        System.Threading.Thread.Sleep(2000)
    End While
End Sub

Public Sub WriteObject(data As ExchangeData)
    Try
        Dim pd As PageData = DirectCast(data.Data, PageData)
        pd.SiteName = pd.SiteName.RegexReplace("-\d{1,2}$", "")
        If (data.Command = ExchangeCommand.PageData) Then
            'something to do
        End If
        If (app.IsShareHtml) Then
            Me.pushClient.SendFrame(serialize(pd.SiteName, pd.GameType, data))
        End If
    Catch ex1 As Exception
        Try
            Me.initializePushClient()
        Catch ex2 As Exception

        End Try
        Try
            exceptionLogger.Warn(ex1, "{0}", "WriteObjectException")
        Catch ex2 As Exception

        End Try
    End Try
End Sub

Private Function serialize(siteName As String, gameType As String, data As ExchangeData) As String
    Dim returnValue = String.Empty
    returnValue = String.Format("{0}|{1}|{2}|{3}|{4}", siteName, gameType, "Username", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), Singmar.IO.Serializer.Compress(Singmar.IO.Serializer.SerializeToByteArray(data), Ionic.Zlib.CompressionLevel.BestCompression).ToBase64String())
    Return returnValue
End Function

Private Function deserialize(data As String) As ExchangeData
    Dim returnValue As ExchangeData = Nothing
    Dim strArray() As String = data.Split("|", StringSplitOptions.RemoveEmptyEntries)
    If (strArray.Length = 5) Then
        Try
            returnValue = DirectCast(Singmar.IO.Serializer.DeserializeFromByteArray(Singmar.IO.Serializer.Decompress(strArray(4).FromBase64String())), ExchangeData)
        Catch ex As Exception

        End Try
    End If
    Return returnValue
End Function

Private Sub initializePushClient()
    Me.pushContext = NetMQ.NetMQContext.Create()
    Me.pushClient = Me.pushContext.CreatePushSocket()
    Me.pushClient.Connect(String.Format("tcp://{0}:8152", Me.serverIp))
End Sub

End Class

End Namespace

I guess my unhandled exception line is Dim str As String = subscriberClient.ReceiveFrameString() or subscriberClient.ReceiveFrameString() , and NetMQ inner thread throws exception from MSG struct Close() method, how do I sove this exception ?? please, thx.

— Reply to this email directly or view it on GitHub https://github.com/zeromq/netmq/issues/394.

ghost commented 9 years ago

Sir, my NetMQ version is 3.3.2.2, AsyncIO version is 0.1.18.

somdoron commented 9 years ago

Any chance you are using the NetMQSocket from multiple threads?

On Sun, Oct 25, 2015 at 11:31 AM, Yojinlin notifications@github.com wrote:

Sir, my NetMQ version is 3.3.2.2, AsyncIO version is 0.1.18.

— Reply to this email directly or view it on GitHub https://github.com/zeromq/netmq/issues/394#issuecomment-150900491.

ghost commented 9 years ago

Yes Sir. clientThreadImplement() method is multiple threads, and WriteObject() method is also multiple threads.

somdoron commented 9 years ago

NetMQ socket are not thread safe, so you must use it from one thread.

On Sun, Oct 25, 2015 at 5:25 PM, Yojinlin notifications@github.com wrote:

Yes Sir. clientThreadImplement() method is multiple threads, and WriteObject() method is also multiple threads.

— Reply to this email directly or view it on GitHub https://github.com/zeromq/netmq/issues/394#issuecomment-150927879.

ghost commented 9 years ago

Sir, I will try to handle thread safe, thank you very much.