private async Task RunAsync() { var host = BuildServiceHost(); var serverHandler = new StreamRpcServerHandler(host); var clientHandler = new StreamRpcClientHandler(); var client = new JsonRpcClient(clientHandler); using (var pipe = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous)) { var connectTask = pipe.ConnectAsync(); hostingClient = BuildHostingClient(client); serverHandler.DefaultFeatures.Set(this); var reader = new ByLineTextMessageReader(pipe) { LeaveReaderOpen = true }; var writer = new ByLineTextMessageWriter(pipe) { LeaveWriterOpen = true }; Ambient = new SandboxAmbient(hostingClient, SandboxId); await connectTask; using (reader) using (writer) using (serverHandler.Attach(reader, writer)) using (clientHandler.Attach(reader, writer)) { // Started up hostingClient.NotifyStarted(); // Wait for disposal await disposalTcs.Task; } } // Dispose if (_ClientModule != null) { if (_ClientModule is IDisposable d) { d.Dispose(); } _ClientModule = null; } // Final cleanup. // The owner will unload appdomain so a ThreadAbortException should be thrown here. hostCallback.NotifySandboxDisposed(SandboxId); }
internal SandboxAmbient(IHostingClient hostingClient, int sandboxId) { this.hostingClient = hostingClient ?? throw new ArgumentNullException(nameof(hostingClient)); SandboxId = sandboxId; Name = "C# Sandbox, " + sandboxId; }