private async Task PrivateRunAsync(CancellationToken cancellationToken)
        {
            using (var pipe = new NamedPipeServerStream(ServerInfo.Name, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    await pipe.WaitForConnectionAsync(cancellationToken);

                    using (var reader = new NonClosingStreamReader(pipe))
                    using (var writer = new NonClosingStreamWriter(pipe) { AutoFlush = true })
                    {
                        var input = await reader.ReadCommandAsync();

                        _log.Information("Retrieved input {Input}", input);

                        switch (input)
                        {
                            case NamedPipeCommand.FindRepo:
                                await writer.WriteAsync(NamedPipeCommand.Ready);
                                await FindRepo(writer, await reader.ReadLineAsync(), cancellationToken);
                                break;
                            case NamedPipeCommand.GetAllRepos:
                                await writer.WriteAsync(NamedPipeCommand.Ready);
                                await GetAllRepos(writer, cancellationToken);
                                break;
                            case NamedPipeCommand.RemoveRepo:
                                await writer.WriteAsync(NamedPipeCommand.Ready);
                                await RemoveRepo(writer, reader, cancellationToken);
                                break;
                            case NamedPipeCommand.ClearCache:
                                await writer.WriteAsync(NamedPipeCommand.Ready);
                                await ProcessClearCacheAsync(writer, cancellationToken);
                                break;
                            case NamedPipeCommand.ExpandGitCommand:
                                await writer.WriteAsync(NamedPipeCommand.Ready);
                                await ProcessExpandGitCommandAsync(writer, reader, cancellationToken);
                                break;
                            default:
                                await writer.WriteAsync(NamedPipeCommand.BadCommand);
                                break;
                        }
                    }

                    // This must be after the reader and writer are closed
                    // Otherwise, an InvalidOperationException is thrown
                    pipe.WaitForPipeDrain();
                    pipe.Disconnect();
                }
            }
        }
        private async Task <T> SendReceiveCommandAsync <T>(Func <StreamReader, StreamWriter, Task <T> > func, NamedPipeCommand command, CancellationToken cancellationToken, T defaultValue = default(T))
        {
            // Time out after 2 seconds to access named pipe
            using (var innerCancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(2)))
            {
                try
                {
                    // Ensure that the named pipe cancellation token gets cancelled if the main token is
                    using (cancellationToken.Register(innerCancellationTokenSource.Cancel))
                        using (var pipe = new NamedPipeClientStream(NamedPipePoshGitServer.ServerName, ServerInfo.Name, PipeDirection.InOut, PipeOptions.Asynchronous))
                        {
                            await pipe.ConnectAsync(innerCancellationTokenSource.Token);

                            using (var writer = new NonClosingStreamWriter(pipe)
                            {
                                AutoFlush = true
                            })
                                using (var reader = new NonClosingStreamReader(pipe))
                                {
                                    await writer.WriteAsync(command);

                                    var response = await reader.ReadCommandAsync();

                                    if (response != NamedPipeCommand.Ready)
                                    {
                                        return(defaultValue);
                                    }

                                    return(await func(reader, writer));
                                }
                        }
                }
                catch (OperationCanceledException)
                {
                    _log.Error("Named pipe communication with server was cancelled");

                    return(defaultValue);
                }
            }
        }
Example #3
0
        private async Task PrivateRunAsync(CancellationToken cancellationToken)
        {
            using (var pipe = new NamedPipeServerStream(ServerInfo.Name, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    await pipe.WaitForConnectionAsync(cancellationToken);

                    using (var reader = new NonClosingStreamReader(pipe))
                        using (var writer = new NonClosingStreamWriter(pipe)
                        {
                            AutoFlush = true
                        })
                        {
                            var input = await reader.ReadCommandAsync();

                            _log.Information("Retrieved input {Input}", input);

                            switch (input)
                            {
                            case NamedPipeCommand.FindRepo:
                                await writer.WriteAsync(NamedPipeCommand.Ready);
                                await FindRepo(writer, await reader.ReadLineAsync(), cancellationToken);

                                break;

                            case NamedPipeCommand.GetAllRepos:
                                await writer.WriteAsync(NamedPipeCommand.Ready);
                                await GetAllRepos(writer, cancellationToken);

                                break;

                            case NamedPipeCommand.RemoveRepo:
                                await writer.WriteAsync(NamedPipeCommand.Ready);
                                await RemoveRepo(writer, reader, cancellationToken);

                                break;

                            case NamedPipeCommand.ClearCache:
                                await writer.WriteAsync(NamedPipeCommand.Ready);
                                await ProcessClearCacheAsync(writer, cancellationToken);

                                break;

                            case NamedPipeCommand.ExpandGitCommand:
                                await writer.WriteAsync(NamedPipeCommand.Ready);
                                await ProcessExpandGitCommandAsync(writer, reader, cancellationToken);

                                break;

                            default:
                                await writer.WriteAsync(NamedPipeCommand.BadCommand);

                                break;
                            }
                        }

                    // This must be after the reader and writer are closed
                    // Otherwise, an InvalidOperationException is thrown
                    pipe.WaitForPipeDrain();
                    pipe.Disconnect();
                }
            }
        }