예제 #1
0
        private async Task<BuildResponse> DoCompilationAsync(NamedPipeClientStream pipeStream,
                                                        BuildRequest req,
                                                        CancellationToken cancellationToken)
        {
            using (pipeStream)
            {
                try
                {
                    // Start a monitor that cancels if the pipe closes on us
                    var monitorCancellation = new CancellationTokenSource();
                    Task disconnectMonitor = MonitorPipeForDisconnectionAsync(pipeStream, monitorCancellation.Token);

                    // Write the request.
                    CompilerServerLogger.Log("Writing request");
                    await req.WriteAsync(pipeStream, cancellationToken).ConfigureAwait(false);

                    // Read the response.
                    CompilerServerLogger.Log("Reading response");
                    BuildResponse response = await BuildResponse.ReadAsync(pipeStream, cancellationToken).ConfigureAwait(false);

                    // Stop monitoring pipe
                    monitorCancellation.Cancel(throwOnFirstException: true);
                    await disconnectMonitor.ConfigureAwait(false);

                    Debug.Assert(response != null);
                    CompilerServerLogger.Log("BuildResponse received; exit code={0}", response.ReturnCode);

                    return response;
                }
                catch (PipeBrokenException e)
                {
                    CompilerServerLogger.LogException(e, "Server process died; pipe broken.");
                    return null;
                }
                catch (ObjectDisposedException e)
                {
                    CompilerServerLogger.LogException(e, "Pipe stream unexpectedly disposed");
                    return null;
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Try to compile using the server. Returns null if a response from the
        /// server cannot be retrieved.
        /// </summary>
        private static async Task<BuildResponse> TryCompile(NamedPipeClientStream pipeStream,
                                                            BuildRequest request,
                                                            CancellationToken cancellationToken)
        {
            BuildResponse response;
            using (pipeStream)
            {
                // Write the request
                try
                {
                    Log("Begin writing request");
                    await request.WriteAsync(pipeStream, cancellationToken).ConfigureAwait(false);
                    Log("End writing request");
                }
                catch (Exception e)
                {
                    LogException(e, "Error writing build request.");
                    return null;
                }

                // Wait for the compilation and a monitor to detect if the server disconnects
                var serverCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

                Log("Begin reading response");

                var responseTask = BuildResponse.ReadAsync(pipeStream, serverCts.Token);
                var monitorTask = CreateMonitorDisconnectTask(pipeStream, serverCts.Token);
                await Task.WhenAny(responseTask, monitorTask).ConfigureAwait(false);

                Log("End reading response");

                if (responseTask.IsCompleted)
                {
                    // await the task to log any exceptions
                    try
                    {
                        response = await responseTask.ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        LogException(e, "Error reading response");
                        response = null;
                    }
                }
                else
                {
                    Log("Server disconnect");
                    response = null;
                }

                // Cancel whatever task is still around
                serverCts.Cancel();
                return response;
            }
        }