vb.Net - Именованные каналы - NamedPipeServerStream - StackOverflowException - PullRequest
0 голосов
/ 08 мая 2018

Я пытаюсь использовать именованные каналы для связи между службой Windows и приложением WPF, оба написаны на VB.Net. Служба windows всегда работает.

Однако после нескольких часов работы приложения WPF выдается StackOverflowException.

PipeServerThread() в приложении WPF - единственная функция, которая неоднократно вызывается в управляемом стеке во время исключения (я отслеживал это, используя WinDbg).

Сервис содержит NamedPipeClientStream, Приложение содержит NamedPipeServerStream.

Когда клиент и сервер взаимодействуют, сервер считывает окончательный ответ клиента после нескольких проверок, а затем передает клиентскую строку функции в другом месте кода.

Трубный сервер затем промывается, закрывается и утилизируется.

Затем снова вызывается PipeServerThread(), чтобы создать еще один конвейерный сервер для связи. Обратите внимание, что PipeServerThread () вызывается повторно.

Может ли кто-нибудь пролить свет на то, что в коде в конечном итоге вызывает StackOverflowException?

PipeServer:

Dim PipeServers(1) As Thread
PipeServers(1) = New Thread(AddressOf PipeServerThread)
PipeServers(1).IsBackground = True
PipeServers(1).Start()

Private Sub PipeServerThread()

    Dim ps = New System.IO.Pipes.PipeSecurity

    Try
        ps.AddAccessRule(New System.IO.Pipes.PipeAccessRule("Users", System.IO.Pipes.PipeAccessRights.FullControl, System.Security.AccessControl.AccessControlType.Allow))
        ps.AddAccessRule(New System.IO.Pipes.PipeAccessRule("CREATOR OWNER", System.IO.Pipes.PipeAccessRights.FullControl, System.Security.AccessControl.AccessControlType.Allow))
        ps.AddAccessRule(New System.IO.Pipes.PipeAccessRule("SYSTEM", System.IO.Pipes.PipeAccessRights.FullControl, System.Security.AccessControl.AccessControlType.Allow))

        Dim pipeserver = New System.IO.Pipes.NamedPipeServerStream("testpipe", Pipes.PipeDirection.InOut, 10, Pipes.PipeTransmissionMode.Byte, Pipes.PipeOptions.None, 4024, 4024, ps)

        Debug.WriteLine("Pipeserver waiting for connection")
        pipeserver.WaitForConnection()
        Try
            'Debug.WriteLine("Pipeserver now within Try block.")
            Dim ss As New StreamString(pipeserver)
            'This server writes to pipe immediately on connection
            Debug.WriteLine("Server now writing to Pipe")
            ss.WriteString("Hello Client. Who are you?")                                            'Action 1 - server writes to Pipe

            'Response from client is read
            Dim ClientName As String = ss.ReadString                                                'Action 4 - server reads from Pipe
            Debug.WriteLine("Client's name is: " & ClientName)
            If ClientName = "PipeWriterService" Then
                'The client is the PipeWriterService
                'Tell it what state is being requested
                ss.WriteString(RequestedCommState)                                                  'Action 5 (if) - server writes to Pipe
            Else
                'The client is someting else
                ss.WriteString("wrong client")                                                      'Action 5 (else) - server writes to Pipe
            End If

            Dim ClientResponse As String = ss.ReadString()
            Debug.WriteLine("Server has read client Response as: " & ClientResponse)                'Action 8 - server reads from Pipe
            DeviceInfo.Dispatcher.BeginInvoke(Windows.Threading.DispatcherPriority.Normal, New OneArgDelegate3(AddressOf ProcessPipeString), ClientResponse)
        Catch ex As Exception
            Debug.WriteLine("Error is Server Try block: " & ex.Message)
        End Try
        pipeserver.Flush()
        pipeserver.Close()                                                                          'Action 9 - server closes Pipe
        pipeserver.Dispose()
        Debug.WriteLine("PipeServer now closed")
    Catch ex As Exception

    End Try

    Call PipeServerThread()
End Sub

PipeClient:

    Private Sub PipeWriter(StringToWrite As String)
    Dim pipeClient As New NamedPipeClientStream(".", "testpipe", PipeDirection.InOut, PipeOptions.None)
    Try
        pipeClient.Connect(50)
        Dim ss As New StreamString(pipeClient)
        'Once a connection is established, Server will write to pipe first
        'This is read by the client in the line below
        Debug.WriteLine("First string from Server: " & ss.ReadString())                             'Action 2: Client Reads from Pipe
        'Server is now waiting. This client responds with its name
        ss.WriteString("PipeWriterService")                                                           'Action 3: Client Writes to Pipe
        'Server will respond again
        'This is read by the client in the line below
        RequestedCommState = ss.ReadString()                                                    'Action 6: Client reads from Pipe
        Debug.WriteLine("Second string from Server: " & RequestedCommState)
        'This response contains the desired 3G comm status from the server
        'Server is now waiting. This client responds with whatever it wants to say to server
        ss.WriteString(StringToWrite)                                                               'Action 7: Client writes to Pipe
    Catch ex As Exception
        Debug.WriteLine("Error in PipeWriter. Error is: " & ex.Message)
    End Try

End Sub

1 Ответ

0 голосов
/ 18 января 2019

Возможно, вы уже решили проблему на данный момент.

В любом случае проблема заключается в рекурсивном вызове в PipeServerThread (). Каждый раз, когда вы вызываете его, размер стека увеличивается для хранения локальных переменных и адреса возврата функции.

Вы должны избавиться от рекурсивного вызова и поместить тело функции в цикл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...