internal MethodReply(MethodReply reply) : base(reply) { }
public static async Task <TResult> CallAsync <TResult>(this IConnection connection, string method, Func <string, System.Type> errorParametersType) { MethodReply <TResult> reply = await connection.CallMethodAsync <TResult>(method, errorParametersType, parameters : null, CallFlags.ThrowOnError); return(reply.parameters); }
public async Task <MethodReply <TResult> > CallMethodAsync <TResult>(string method, Func <string, System.Type> errorParametersType, object parameters, CallFlags flags) { try { int prevState = Interlocked.CompareExchange(ref _state, StateBusy, StateNone); if (prevState == StateBusy) { throw new InvalidOperationException("Concurrent operations are not supported."); } else if (prevState == StateDisposed) { throw new ObjectDisposedException(typeof(Connection).FullName); } if (!_connected) { ParseAddress(_address, out _socket, out _endPoint); await _socket.ConnectAsync(_endPoint); _connected = true; } MethodCall <object> call = new MethodCall <object> { parameters = parameters, method = method, oneway = false, upgrade = false }; string serializedCall = JsonConvert.SerializeObject(call); await _socket.SendAsync(Encoding.UTF8.GetBytes(serializedCall), SocketFlags.None); // TODO: why didn't this throw without ConnectAsync await _socket.SendAsync(new byte[] { 0 }, SocketFlags.None); _memoryStream.SetLength(0); bool eom = false; do { int length = await _socket.ReceiveAsync(_readBuffer.AsMemory(), SocketFlags.None); if (length == 0) { throw new IOException("Unexpected end of stream."); } _memoryStream.Write(_readBuffer, 0, length); for (int i = 0; i < length; i++) { if (_readBuffer[i] == 0) { eom = true; } } } while (!eom); _memoryStream.Position = 0; _streamReader.DiscardBufferedData(); MethodReply reply = (MethodReply)_serializer.Deserialize(_streamReader, typeof(MethodReply)); _memoryStream.Position = 0; _streamReader.DiscardBufferedData(); MethodReply <TResult> result; if (reply.error != null) { result = new MethodReply <TResult>(reply); System.Type errorType = errorParametersType?.Invoke(reply.error); if (errorType != null) { var replyWithErrorParameters = (MethodReply)_serializer.Deserialize(_streamReader, typeof(MethodReply <>).MakeGenericType(errorType)); result.ErrorParameters = replyWithErrorParameters.GetParameters(); } if ((flags & CallFlags.ThrowOnError) != CallFlags.None) { result.ThrowOnError(); } } else { result = (MethodReply <TResult>)_serializer.Deserialize(_streamReader, typeof(MethodReply <TResult>)); } return(result); } catch { _socket?.Dispose(); _connected = false; throw; } finally { int prevState = Interlocked.CompareExchange(ref _state, StateNone, StateBusy); if (prevState == StateDisposed) { _socket?.Dispose(); } } }