private async Task <TResult> ExecuteAsync <TResult>(LambdaExpression methodCall) { var body = (MethodCallExpression)methodCall.Body; var methodInfo = body.Method; var args = body.Arguments.Select(arg => Expression.Lambda(arg).Compile().DynamicInvoke()).ToArray(); if (methodInfo.IsAbstract || methodInfo.IsPrivate || !methodInfo.IsStatic || methodInfo.DeclaringType.IsNotPublic) { throw new ArgumentException(); } if (methodInfo.GetCustomAttribute <ProcDomainExportAttribute>(inherit: false) == null) { throw new ArgumentException(); } var request = new CrossDomainInvokeRequest() { Method = methodInfo, MessageId = Guid.NewGuid(), Arguments = args }; var response = await SendRequestAndWaitAsync(request); if (response.Exception != null) { throw response.Exception; } return((TResult)response.Result); }
private async Task ListenToParentDomainAsync() { CrossDomainInvokeRequest parentMessage = null; //while the we continue to get messages from the parent process while ((parentMessage = await ReadNextRequestAsync()) != null) { Task throwaway = HandleInvokeRequest(parentMessage); } this.Unload(); }
private async Task <CrossDomainInvokeResponse> SendRequestAndWaitAsync(CrossDomainInvokeRequest message) { var taskCompletionSource = new TaskCompletionSource <CrossDomainInvokeResponse>(); //add the transation to the pendingActions before sending the message to avoid a race with completion of the action _pendingActions.Add(message.MessageId, taskCompletionSource); byte[] buff = message.ToByteArray(); await _pipe.WriteAsync(buff, 0, buff.Length); //wait for the response the completion source will be triggered in the ListenForResponsesAsync loop once the //appropriate message has been recieved, (matching messageId) return(await taskCompletionSource.Task); }
private async Task <CrossDomainInvokeRequest> ReadNextRequestAsync() { _pipe.ReadMode = PipeTransmissionMode.Message; byte[] buff = new byte[1024]; MemoryStream memStream = new MemoryStream(); do { int bytesRead = await _pipe.ReadAsync(buff, 0, 1024); if (bytesRead == 0) { return(null); } memStream.Write(buff, 0, bytesRead); } while (!_pipe.IsMessageComplete); return(CrossDomainInvokeRequest.FromByteArray(memStream.ToArray())); }
private async Task HandleInvokeRequest(CrossDomainInvokeRequest request) { //TODO: assembly loading goo? var response = new CrossDomainInvokeResponse() { MessageId = request.MessageId }; try { response.Result = await Task.Run <object>(() => request.Method.Invoke(null, request.Arguments)); } catch (TargetInvocationException e) { response.Exception = e.InnerException; } catch (Exception e) { response.Exception = e; } await SendResponseAsync(response); }