Я использую асинхронные каналы, и в какой-то момент и сервер, и клиент ждут друг друга и ничего не делают. Вот мой код:C# async named pipes wait for ever
Сервер:
var buffer = new byte[BufferSize];
using (var server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
{
// Wait for client.
Logger.Trace("Waiting for connection ...");
var asyncResult = server.BeginWaitForConnection(a => { }, null);
while (true)
{
await Task.Delay(MillisecondsDelay);
if (asyncResult.IsCompleted) break;
}
server.EndWaitForConnection(asyncResult);
Logger.Trace("Connection established.");
using (var sr = new StreamReader(server))
using (var sw = new StreamWriter(server))
{
// Send work.
Logger.Trace("Sending operations...");
await sw.WriteAsync(JsonConvert.SerializeObject(data));
await sw.FlushAsync();
server.WaitForPipeDrain();
// Wait for response.
var bytesRead = await server.ReadAsync(buffer, 0, buffer.Length);
.....
Клиент:
// Read data from the pipe...
using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous))
{
Logger.Trace("Connecting to server...");
client.Connect();
Logger.Trace("Connected.");
using (var sr = new StreamReader(client))
using (var sw = new StreamWriter(client))
{
// Read operations.
Logger.Trace("Waiting operations...");
var text = await sr.ReadToEndAsync();
.....
Бревна, что я беру такие:
2016-10-04 16:09:51.5375 => (TRACE) | MyController.Execute : Waiting for connection ... |
2016-10-04 16:09:52.0706 => (TRACE) | MyController+<Execute>d__5.MoveNext : Connection established. |
2016-10-04 16:09:52.0706 => (TRACE) | MyController+<Execute>d__5.MoveNext : Sending operations... |
и:
2016-10-04 16:09:51.8486 => (TRACE) | EXE.Program.Process : Connecting to server... |
2016-10-04 16:09:51.8696 => (TRACE) | EXE.Program.Process : Connected. |
2016-10-04 16:09:51.8696 => (TRACE) | EXE.Program.Process : Waiting operations... |
А потом ничего!
После этого он кажется запертым.
Я думаю, что я должен использовать WaitForPipeDrain()
после каждой записи сервером или клиентом, и я это делаю, но, похоже, это не помогает.
Операция чтения клиента никогда не возвращается.
Любые идеи кто-нибудь?
Когда вы говорите «ReadToEndAsync», как читатель потока знает, что он в конце? Неужели он все еще тупик, если вы используете 'ReadAsync'? – DavidG
@DavidG Мое предположение заключалось в том, что * был * конец потока (где нет других данных для чтения), несмотря на то, что поток не закрыт. Поэтому я считаю, что он сможет прочитать содержимое с текущей позиции до конца текущего размера потока. И я также просто попытался использовать 'ReadLineAsync()' вместо этого, и он все еще имеет ту же проблему. 'ReadAsync' читает байтовые массивы, поэтому для этого потребуется больше рефакторинга ... – user2173353
Ну,' ReadLine' подразумевает, что существует строка, которая может отсутствовать. Вы также можете попробовать использовать 'ConfigureAwait (false)' на ваших ожиданиях. – DavidG