命名管道接收消息时创建对象

时间:2015-08-16 23:16:09

标签: vb.net multithreading named-pipes

我一直在使用Mutex创建单个实例应用程序。

Sub Main代码中,应用会检查它是否是第一个实例,如果是,则启动表单(称为MainForm)。 MainForm创建一个异步命名管道服务器来接收从新实例传递的参数。

如果应用程序不是第一个实例,则Sub Main会创建一个命名管道客户端,将命令行参数发送到第一个应用程序,然后继续退出。

应用程序是基于选项卡的,每个命令行参数都是一个文件路径,用于创建选项卡。接收到的论点(我可以MsgBox()),但是当我尝试将其作为参数传递给我创建的控件时,没有任何反应

Pipe课程:

Namespace Pipes

' Delegate for passing received message back to caller
Public Delegate Sub DelegateMessage(Reply As String)

Public Class PipeServer
    Public Event PipeMessage As DelegateMessage
    Private _pipeName As String

    Public Sub Listen(PipeName As String)
        Try
            ' Set to class level var so we can re-use in the async callback method
            _pipeName = PipeName
            ' Create the new async pipe 
            Dim pipeServer As New NamedPipeServerStream(PipeName, PipeDirection.[In], 1, PipeTransmissionMode.[Byte], PipeOptions.Asynchronous)

            ' Wait for a connection
            pipeServer.BeginWaitForConnection(New AsyncCallback(AddressOf WaitForConnectionCallBack), pipeServer)
        Catch oEX As Exception
            Debug.WriteLine(oEX.Message)
        End Try
    End Sub

    Private Sub WaitForConnectionCallBack(iar As IAsyncResult)
        Try
            ' Get the pipe
            Dim pipeServer As NamedPipeServerStream = DirectCast(iar.AsyncState, NamedPipeServerStream)
            ' End waiting for the connection
            pipeServer.EndWaitForConnection(iar)

            Dim buffer As Byte() = New Byte(254) {}

            ' Read the incoming message
            pipeServer.Read(buffer, 0, 255)

            ' Convert byte buffer to string
            Dim stringData As String = Encoding.UTF8.GetString(buffer, 0, buffer.Length)
            Debug.WriteLine(stringData + Environment.NewLine)

            ' Pass message back to calling form
            RaiseEvent PipeMessage(stringData)

            ' Kill original sever and create new wait server
            pipeServer.Close()
            pipeServer = Nothing
            pipeServer = New NamedPipeServerStream(_pipeName, PipeDirection.[In], 1, PipeTransmissionMode.[Byte], PipeOptions.Asynchronous)

            ' Recursively wait for the connection again and again....
            pipeServer.BeginWaitForConnection(New AsyncCallback(AddressOf WaitForConnectionCallBack), pipeServer)
        Catch
            Return
        End Try
    End Sub
End Class

Class PipeClient
    Public Sub Send(SendStr As String, PipeName As String, Optional TimeOut As Integer = 1000)
        Try
            Dim pipeStream As New NamedPipeClientStream(".", PipeName, PipeDirection.Out, PipeOptions.Asynchronous)

            ' The connect function will indefinitely wait for the pipe to become available
            ' If that is not acceptable specify a maximum waiting time (in ms)
            pipeStream.Connect(TimeOut)
            Debug.WriteLine("[Client] Pipe connection established")

            Dim _buffer As Byte() = Encoding.UTF8.GetBytes(SendStr)
            pipeStream.BeginWrite(_buffer, 0, _buffer.Length, AddressOf AsyncSend, pipeStream)
        Catch oEX As TimeoutException
            Debug.WriteLine(oEX.Message)
        End Try
    End Sub

    Private Sub AsyncSend(iar As IAsyncResult)
        Try
            ' Get the pipe
            Dim pipeStream As NamedPipeClientStream = DirectCast(iar.AsyncState, NamedPipeClientStream)

            ' End the write
            pipeStream.EndWrite(iar)
            pipeStream.Flush()
            pipeStream.Close()
            pipeStream.Dispose()
        Catch oEX As Exception
            Debug.WriteLine(oEX.Message)
        End Try
    End Sub
End Class
End Namespace

MainForm逻辑:

#Region "Pipes"
Public ArgumentPipe As New Pipes.PipeServer
Public Sub RecievedMessage(reply As String)
    GetMainformHook.Invoke(MySTDelegate, reply)
End Sub

Public Sub InitializeServer()
    AddHandler ArgumentPipe.PipeMessage, AddressOf RecievedMessage
    ArgumentPipe.Listen(_pipename)
End Sub

Public Delegate Sub RecievedMessageDel(txt As String)
Public MySTDelegate As RecievedMessageDel = AddressOf SetText
Public Sub SetText(txt)
    MsgBox(txt)
    TabStrip1.AddTab(txt.ToString)  'PROBLEM OCCURS HERE
End Sub

Public Shared Function GetMainformHook() As MainForm
    Return Application.OpenForms("MainForm")
End Function

Public Shared Function GetTabControl() As TabStrip
    Return CType(Application.OpenForms("MainForm"), MainForm).TabStrip1
End Function

Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
     InitializeServer()
End Sub

#End Region

发送参数时Sub Main

Dim _pipeClient = New Pipes.PipeClient()

If cmdArgs.Length > 0 Then
    For i = 0 To cmdArgs.Length - 1
        _pipeClient.Send(cmdArgs(i), _pipename, 1000)
    Next
End If

_pipename是一个全局字符串,如"myappv6"

我错过了什么吗?

我认为这与交叉线程有关,但无法确定解决问题的位置。

由于

0 个答案:

没有答案