Created
August 26, 2020 15:09
-
-
Save antonfirsov/ce0cb4992e115bb4d6e8dd6862fd6780 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.IO.Pipes; | |
using System.Threading; | |
using System.Threading.Tasks; | |
namespace KilledByPipes | |
{ | |
class Program | |
{ | |
static async Task Main(string[] args) | |
{ | |
System.Console.WriteLine("Runnin ...."); | |
for (int j = 0; j < 10; j++) | |
{ | |
string name = "test" + j; | |
// Launch the listeners: | |
_ = ListenCoreAsync(name); | |
for (int i = 0; i < 100; i++) | |
{ | |
await Task.Factory.StartNew(async () => { | |
var client = await TryConnectToServerAsync(name, 1000); | |
client.Dispose(); | |
}, TaskCreationOptions.LongRunning); | |
} | |
} | |
System.Console.WriteLine("Done but finalizer thread will hang :("); | |
} | |
private static async Task ListenCoreAsync( | |
string pipeName) | |
{ | |
while (true) | |
{ | |
NamedPipeServerStream pipeStream = null; | |
try | |
{ | |
pipeStream = CreateServer(pipeName); | |
await pipeStream.WaitForConnectionAsync().ConfigureAwait(false); | |
pipeStream = null; | |
} | |
catch | |
{ | |
pipeStream?.Dispose(); | |
} | |
} | |
} | |
private static NamedPipeServerStream CreateServer(string pipeName, PipeDirection? pipeDirection = null) | |
{ | |
var pipeOptions = PipeOptions.Asynchronous | PipeOptions.WriteThrough; | |
return CreateServer( | |
pipeName, | |
pipeDirection ?? PipeDirection.InOut, | |
NamedPipeServerStream.MaxAllowedServerInstances, | |
PipeTransmissionMode.Byte, | |
pipeOptions, | |
0x10000, | |
0x10000); | |
} | |
private static NamedPipeServerStream CreateServer( | |
string pipeName, | |
PipeDirection direction, | |
int maxNumberOfServerInstances, | |
PipeTransmissionMode transmissionMode, | |
PipeOptions options, | |
int inBufferSize, | |
int outBufferSize) => | |
new NamedPipeServerStream( | |
GetPipeNameOrPath(pipeName), | |
direction, | |
maxNumberOfServerInstances, | |
transmissionMode, | |
options | PipeOptions.CurrentUserOnly, | |
inBufferSize, | |
outBufferSize); | |
private static string GetPipeNameOrPath(string pipeName) => Path.Combine("/tmp", pipeName); | |
internal static async Task<NamedPipeClientStream> TryConnectToServerAsync( | |
string pipeName, | |
int timeoutMs) | |
{ | |
NamedPipeClientStream pipeStream = null; | |
try | |
{ | |
pipeStream = CreateClient(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous); | |
await Task.Run(() => pipeStream.ConnectAsync(timeoutMs)).ConfigureAwait(false); | |
return pipeStream; | |
} | |
catch | |
{ | |
pipeStream.Dispose(); | |
return null; | |
} | |
} | |
private static NamedPipeClientStream CreateClient(string serverName, string pipeName, PipeDirection direction, PipeOptions options) | |
=> new NamedPipeClientStream(serverName, GetPipeNameOrPath(pipeName), direction, options | PipeOptions.CurrentUserOnly); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment