vb.Net- 命名管道 - NamedPipeServerStream - StackOverflowException
vb.Net- Named Pipes - NamedPipeServerStream - StackOverflowException
我正在尝试使用命名管道在 windows 服务和 WPF 应用程序之间进行通信,两者都是用 VB.Net 编写的。 windows 服务始终是 运行。
然而,在 运行 几个小时后,WPF 应用程序 WhosebugException
被抛出。
WPF 应用程序中的 PipeServerThread()
是唯一在异常发生时在托管堆栈中重复调用的函数(我使用 WinDbg
追踪到它)。
服务包含NamedPipeClientStream
,应用程序包含NamedPipeServerStream
。
当客户端和服务器通信时,服务器在经过几次检查后读取最终的客户端响应,然后将客户端字符串传递给代码中其他地方的函数。
然后冲洗、关闭和处置管道服务器。
然后再次调用PipeServerThread()
创建另一个管道服务器进行通信。请注意此 PipeServerThread() 被重复调用。
谁能阐明代码中最终导致 WhosebugException
发生的原因?
管道服务器:
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
管道客户端:
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
可能您此时已经解决了问题。
无论如何,问题是在 PipeServerThread() 中的重新递归调用。每次调用它时,堆栈的大小都会增加以容纳局部变量和函数的 return 地址。
你必须摆脱递归调用并将函数体放入循环中。
我正在尝试使用命名管道在 windows 服务和 WPF 应用程序之间进行通信,两者都是用 VB.Net 编写的。 windows 服务始终是 运行。
然而,在 运行 几个小时后,WPF 应用程序 WhosebugException
被抛出。
PipeServerThread()
是唯一在异常发生时在托管堆栈中重复调用的函数(我使用 WinDbg
追踪到它)。
服务包含NamedPipeClientStream
,应用程序包含NamedPipeServerStream
。
当客户端和服务器通信时,服务器在经过几次检查后读取最终的客户端响应,然后将客户端字符串传递给代码中其他地方的函数。
然后冲洗、关闭和处置管道服务器。
然后再次调用PipeServerThread()
创建另一个管道服务器进行通信。请注意此 PipeServerThread() 被重复调用。
谁能阐明代码中最终导致 WhosebugException
发生的原因?
管道服务器:
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
管道客户端:
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
可能您此时已经解决了问题。
无论如何,问题是在 PipeServerThread() 中的重新递归调用。每次调用它时,堆栈的大小都会增加以容纳局部变量和函数的 return 地址。
你必须摆脱递归调用并将函数体放入循环中。