|
''' <summary>
''' Listens for connections from named pipe clients.
''' </summary>
''' <remarks></remarks>
Public Class PipeListener
Implements IDisposable
Private ListenningThread As Threading.Thread
Private ThreadSyncControl As New System.Windows.Forms.Control
Private mStopEvent As New Threading.ManualResetEvent(False)
Private mSyncEvent As New Threading.ManualResetEvent(False)
''' <summary>
''' Occurs when a named pipe client connects.
''' </summary>
''' <remarks></remarks>
Public Event ClientConnected As EventHandler(Of ClientConnectedEventArgs)
#Region "Constructors "
''' <summary>
''' Instantiates the PipeListenner with a bufferSize of 16,384 bytes and a unique name(based on Guid.NewGuid).
''' </summary>
''' <remarks></remarks>
Public Sub New()
Me.New(Guid.NewGuid.ToString)
End Sub
''' <summary>
''' Instantiates the PipeListenner with a bufferSize of 2048 bytes.
''' </summary>
''' <param name="Name">Pipe name. Must be up to 246 characters long and without backslashes (\).</param>
''' <remarks></remarks>
Public Sub New(ByVal name As String)
Me.New(name, 2048)
End Sub
''' <summary>
''' Instantiates the PipeListenner class.
''' </summary>
''' <param name="Name">Pipe name. Must be up to 246 characters long and without backslashes (\).</param>
''' <param name="bufferSize">The size of the input/output buffers.</param>
''' <remarks></remarks>
Public Sub New(ByVal name As String, ByVal bufferSize As Integer)
mBufferSize = bufferSize
mName = name
ThreadSyncControl.CreateControl()
End Sub
#End Region
#Region "Public Properties "
Private mBufferSize As Integer
''' <summary>
''' Returns the input/output buffer size passed in to the constructor.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property BufferSize() As Integer
Get
Return mBufferSize
End Get
End Property
Dim mName As String
''' <summary>
''' Pipe name. Must be up to 246 characters long and without backslashes (\).
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property Name() As String
Get
Return mName
End Get
End Property
Private mListenning As Boolean
''' <summary>
''' Returns True if the listenner is waiting for incoming connections.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property Listenning() As Boolean
Get
Return mListenning
End Get
End Property
#End Region
#Region "Control Methods "
Public Sub StartListenning()
If mListenning Then Throw New InvalidOperationException("Already listenning.")
mListenning = True
ListenningThread = New Threading.Thread(AddressOf OnServiceRequest)
ListenningThread.IsBackground = True
ListenningThread.Start()
mSyncEvent.WaitOne(-1, False)
mSyncEvent.Reset()
End Sub
Public Sub StopListenning()
If Not mListenning Then
Throw New InvalidOperationException("Not listenning.")
End If
mListenning = False
mStopEvent.Set()
mSyncEvent.WaitOne(-1, False)
mSyncEvent.Reset()
End Sub
#End Region
#Region "Private Methods"
Private Sub OnServiceRequest()
Dim Async As IAsyncResult, eventRaiser As New iInvokeEvent(AddressOf InvokeEvent)
'Dim mSyncEvents As IntPtr() = {mStopEvent.Handle, Nothing} 'This should be uncommented for final build?! lol
Dim mSyncEvents As Threading.EventWaitHandle() = {mStopEvent, Nothing}
mSyncEvent.Set()
Dim ServerPipe As ServerPipeInstance
Do
ServerPipe = New ServerPipeInstance(Name, IO.FileAccess.ReadWrite, mBufferSize, True)
Async = ServerPipe.BeginConnect(Nothing, Nothing)
If Not Async.CompletedSynchronously Then
'mSyncEvents(1) = Async.AsyncWaitHandle.Handle 'Final build
mSyncEvents(1) = Async.AsyncWaitHandle
'Select Case NativeMethods.WaitForMultipleObjects(mSyncEvents.Length, mSyncEvents, False, UInteger.MaxValue) 'Final build
Select Case Threading.WaitHandle.WaitAny(mSyncEvents, -1, True)
Case 0 'Signal by application thread
Debug.WriteLine(Now.ToShortTimeString & ": Exiting")
mStopEvent.Reset()
Exit Do
Case 1 'Signal by OS - Client Connected
ServerPipe.EndConnect(Async)
Dim args As New ClientConnectedEventArgs(ServerPipe)
If Me.ThreadSyncControl.InvokeRequired Then
Me.ThreadSyncControl.BeginInvoke(eventRaiser, New Object() {args})
Else
eventRaiser.BeginInvoke(args, Nothing, Nothing)
End If
End Select
Else
ServerPipe.EndConnect(Async)
Dim args As New ClientConnectedEventArgs(ServerPipe)
If Me.ThreadSyncControl.InvokeRequired Then
Me.ThreadSyncControl.BeginInvoke(eventRaiser, New Object() {args})
Else
eventRaiser.BeginInvoke(args, Nothing, Nothing)
End If
End If
Loop Until Not mListenning
If Not Async Is Nothing Then
If Not Async.IsCompleted Then
ServerPipe.Disconnect()
ServerPipe.Dispose()
End If
End If
mSyncEvent.Set()
End Sub
Private Delegate Sub iInvokeEvent(ByVal args As EventArgs)
Private Sub InvokeEvent(ByVal args As EventArgs)
If TypeOf args Is ClientConnectedEventArgs Then
RaiseEvent ClientConnected(Me, args)
End If
End Sub
#End Region
#Region " IDisposable Support "
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Private disposedValue As Boolean = False ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
'TODO: Check for any resources that should be free (none at first glance)
End If
Me.disposedValue = True
End Sub
#End Region
End Class
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.
A list of licenses authors might use can be found here