Skip to content
This repository has been archived by the owner on Jun 1, 2020. It is now read-only.

Commit

Permalink
Manual merge pull request 13
Browse files Browse the repository at this point in the history
  • Loading branch information
jameswestgate committed Apr 13, 2020
1 parent af2fc08 commit 4d30b62
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 1 deletion.
31 changes: 30 additions & 1 deletion NamedPipeWrapper/NamedPipeClient.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading;
using NamedPipeWrapper.IO;
using NamedPipeWrapper.Native;
using NamedPipeWrapper.Threading;

namespace NamedPipeWrapper
Expand Down Expand Up @@ -219,13 +221,40 @@ public static PipeStreamWrapper<TRead, TWrite> Connect<TRead, TWrite>(string pip
public static NamedPipeClientStream CreateAndConnectPipe(string pipeName, string serverName)
{
var pipe = CreatePipe(pipeName, serverName);
pipe.Connect();
ConnectWithRetry(pipe, Path.GetFullPath($@"\\{serverName}\pipe\{pipeName}"));
return pipe;
}

private static NamedPipeClientStream CreatePipe(string pipeName,string serverName)
{
return new NamedPipeClientStream(serverName, pipeName, PipeDirection.InOut, PipeOptions.Asynchronous | PipeOptions.WriteThrough);
}

private static void ConnectWithRetry(NamedPipeClientStream pipe, string fullPath)
{
var connected = false;
var resetEvent = new ManualResetEvent(false);

while (!connected)
{
if (!Kernel32.WaitNamedPipe(fullPath, 0xffffffff))
{
resetEvent.WaitOne(100); // prevent cpu spin
}
else
{
try
{
// NamedPipeClientStream.Connect() defaults to a timeout value of -1, which blocks and spins the CPU, provide a sensible timeout value for Connect().
pipe.Connect(15000);
connected = true;
}
catch (TimeoutException)
{
connected = false;
}
}
}
}
}
}
1 change: 1 addition & 0 deletions NamedPipeWrapper/NamedPipeWrapper.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<Compile Include="IO\PipeStreamReader.cs" />
<Compile Include="IO\PipeStreamWrapper.cs" />
<Compile Include="IO\PipeStreamWriter.cs" />
<Compile Include="Native\Kernel32.cs" />
<Compile Include="PipeExceptionEventHandler.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="NamedPipeServer.cs" />
Expand Down
17 changes: 17 additions & 0 deletions NamedPipeWrapper/Native/Kernel32.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Runtime.InteropServices;

namespace NamedPipeWrapper.Native
{
internal sealed class Kernel32
{
/// <summary>
/// Waits until either a time-out interval elapses or an instance of the specified named pipe is available for connection
/// </summary>
/// <param name="lpNamedPipeName">The name of the named pipe. The string must include the name of the computer on which the server process is executing.</param>
/// <param name="nTimeOut">If no instances of the specified named pipe exist, the WaitNamedPipe function returns immediately, regardless of the time-out value.</param>
/// <returns></returns>
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool WaitNamedPipe(string lpNamedPipeName, uint nTimeOut);
}
}

0 comments on commit 4d30b62

Please sign in to comment.