NamedPipeClientStream.ReadAsync() continuously reads after the first message arrives

How come NamedPipeClientStream.ReadAsync continuously reads 0 bytes after the first message arrives? Basically is there a way to have it asynchronously wait until more data arrives after the first message?
2 Replies
Omnissiah
Omnissiah6mo ago
uhm im pretty sure if the result is 0 there are no more bytes, stream is finished (like, marked finished from the other side)
nathanAjacobs
nathanAjacobsOP6mo ago
I don't believe I'm intentionally finishing the server stream, here is my code:
public class ServerPipe : IDisposable
{
readonly SemaphoreSlim semapohre = new SemaphoreSlim(0, 1);

readonly NamedPipeServerStream server;

readonly StreamWriter writer;

private volatile bool _disposed;

public ServerPipe()
{
server = new NamedPipeServerStream("MyTestPipe", PipeDirection.Out);
writer = new StreamWriter(server, System.Text.Encoding.Unicode);
_ = WaitForConnectiionAsync();
}

private async Task WaitForConnectiionAsync()
{
try
{
await server.WaitForConnectionAsync().ConfigureAwait(false);
semapohre.Release();
}
catch (Exception ex)
{
Debug.LogException(ex);
}
}

public async void WriteMessage(string message)
{
if (_disposed)
return;

try
{
await semapohre.WaitAsync().ConfigureAwait(false);
await writer.WriteLineAsync(message).ConfigureAwait(false);
await writer.FlushAsync().ConfigureAwait(false);
}
catch (Exception ex)
{
Debug.LogException(ex);
}
finally
{
semapohre.Release();
Dispose();
}
}

public void Dispose()
{
_disposed = true;
semapohre.Dispose();
writer.Dispose();
server.Dispose();
}
}

public class ClientPipe : IDisposable
{
readonly NamedPipeClientStream client;
readonly StreamReader reader;

public ClientPipe()
{
client = new NamedPipeClientStream(".", "MyTestPipe", PipeDirection.In);
reader = new StreamReader(client);
_ = RunReadLoopAsync();
}

private async Task RunReadLoopAsync()
{
try
{
await client.ConnectAsync();

while (true)
{
string line = await reader.ReadLineAsync();
Debug.Log(line);
}
}
catch (Exception ex)
{
Debug.LogException(ex);
}
}

public void Dispose()
{
reader.Dispose();
client.Dispose();
}
}
public class ServerPipe : IDisposable
{
readonly SemaphoreSlim semapohre = new SemaphoreSlim(0, 1);

readonly NamedPipeServerStream server;

readonly StreamWriter writer;

private volatile bool _disposed;

public ServerPipe()
{
server = new NamedPipeServerStream("MyTestPipe", PipeDirection.Out);
writer = new StreamWriter(server, System.Text.Encoding.Unicode);
_ = WaitForConnectiionAsync();
}

private async Task WaitForConnectiionAsync()
{
try
{
await server.WaitForConnectionAsync().ConfigureAwait(false);
semapohre.Release();
}
catch (Exception ex)
{
Debug.LogException(ex);
}
}

public async void WriteMessage(string message)
{
if (_disposed)
return;

try
{
await semapohre.WaitAsync().ConfigureAwait(false);
await writer.WriteLineAsync(message).ConfigureAwait(false);
await writer.FlushAsync().ConfigureAwait(false);
}
catch (Exception ex)
{
Debug.LogException(ex);
}
finally
{
semapohre.Release();
Dispose();
}
}

public void Dispose()
{
_disposed = true;
semapohre.Dispose();
writer.Dispose();
server.Dispose();
}
}

public class ClientPipe : IDisposable
{
readonly NamedPipeClientStream client;
readonly StreamReader reader;

public ClientPipe()
{
client = new NamedPipeClientStream(".", "MyTestPipe", PipeDirection.In);
reader = new StreamReader(client);
_ = RunReadLoopAsync();
}

private async Task RunReadLoopAsync()
{
try
{
await client.ConnectAsync();

while (true)
{
string line = await reader.ReadLineAsync();
Debug.Log(line);
}
}
catch (Exception ex)
{
Debug.LogException(ex);
}
}

public void Dispose()
{
reader.Dispose();
client.Dispose();
}
}
After the first message arrives it continuously reads null as the line I was being dumb and called dispose in the finally block instead of the catch
Want results from more Discord servers?
Add your server