在字节模式和异步中重用 NamedPipeServerStream 的正确方法

Posted

技术标签:

【中文标题】在字节模式和异步中重用 NamedPipeServerStream 的正确方法【英文标题】:Correct way to Reuse a NamedPipeServerStream in Byte Mode and Asynchronous 【发布时间】:2011-03-31 05:41:38 【问题描述】:

我正在设置一个命名管道服务器,并从服务器管道中读取数据...我允许 5 个可能的并发连接,它们是这样设置的。

Public Sub Start()
    Dim i As Integer
    While i < mTotalServers
        Dim s As New IO.Pipes.NamedPipeServerStream("IPSClient", IO.Pipes.PipeDirection.InOut,
                 mTotalServers, IO.Pipes.PipeTransmissionMode.Byte, IO.Pipes.PipeOptions.Asynchronous)
        i += 1
        Dim p As New PipeConnection(s, "Index - " & i)
        mServers.Add(p)

        s.BeginWaitForConnection(New AsyncCallback(AddressOf ConnectionReceived), p)
    End While
End Sub

然后我恢复操作直到收到连接。

Private Sub ConnectionReceived(ar As IAsyncResult)
    Try
        Dim p As PipeConnection = Nothing
        If ar.IsCompleted Then
            Diagnostics.Debug.Print("Connection received")
            p = CType(ar.AsyncState, PipeConnection)
            Dim s As IO.Pipes.NamedPipeServerStream = p.Stream
            s.EndWaitForConnection(ar)

            Dim conn As Connection = New Connection(p)

            While mRunning AndAlso p.Stream.IsConnected
                If p.ReadHandle.WaitOne(100) Then
                    Debug.Print("Set")
                Else
                    '
                End If
            End While

            If mRunning Then
                s.BeginWaitForConnection(New AsyncCallback(AddressOf ConnectionReceived), p)
            End If
        Else
            p.Stream.Close()
            p.Stream.Dispose()
        End If

    Catch ex As ObjectDisposedException
        ' Diagnostics.Debug.Print(ex.ToString)
    Catch ex As OperationCanceledException
        Diagnostics.Debug.Print(ex.ToString)
    Catch ex As IO.IOException
        Diagnostics.Debug.Print(ex.ToString)
    End Try
End Sub

一旦管道的客户端断开连接,我希望管道可以重复使用。

我在 mRunning 和连接时循环的部分,我应该这样做,还是有更好的方法? (我的阅读代码都发生在Connection Class里面)

在我再次开始等待连接的块的底部,对吗?

【问题讨论】:

【参考方案1】:

...在我再次 BeginWaitForConnection 的块底部,对吗...

不,不是。连接后,NamedPipeServerStream 的实例只是一个 Stream 包裹在将服务器连接到特定客户端的管道实例周围。它不是为重复使用而设计的。您的代码应该只将此实例交给您的 Connection 对象,该对象应确保在与该客户端的通信完成时将其释放。

要重用 mServers 中客户端连接完成后释放的“插槽”,您需要在某个地方实例化一个新的 NamedPipeServerStream 并在其上调用 BeginWaitForConnection。看起来你的 PipeConnection 类可能是实现它的地方。

【讨论】:

天哪,我忘了我什至问过这个问题。是的,从那以后我学到的东西不多:-) 可以通过调用Disconnect 方法重用NamedPipeServer (msdn.microsoft.com/en-us/library/…)

以上是关于在字节模式和异步中重用 NamedPipeServerStream 的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

重用异步套接字:后续连接尝试失败

软件架构和设计模式

异步编程模型

为啥我们需要异步任务以任何方式默认 Web API 请求将仅通过创建或重用现有线程来运行

概念理解同步异步阻塞非阻塞

mongoose.js 中模式部分的共享和重用策略