private void Action <TArgument, TProgress>(AmoebaFunctionType type, TArgument argument, Action <TProgress> progress, CancellationToken token) { var(id, queue) = this.Send(type, argument); try { using (var register = token.Register(() => this.Cancel(id))) { for (; ;) { var info = queue.Dequeue(); try { if (info.Type == AmoebaFunctionResponseType.Result) { return; } else if (info.Type == AmoebaFunctionResponseType.Output) { progress.Invoke(JsonUtils.Load <TProgress>(info.Stream)); } else if (info.Type == AmoebaFunctionResponseType.Cancel) { throw new OperationCanceledException(); } else if (info.Type == AmoebaFunctionResponseType.Error) { throw new AmoebaInterfaceManagerException(JsonUtils.Load <AmoebaErrorMessage>(info.Stream)); } else { throw new NotSupportedException(); } } finally { info.Stream.Dispose(); } } } } finally { queue.Dispose(); _queueMap.Remove(id); } }
private (int, WaitQueue <ResponseInfo>) Send <TArgument>(AmoebaFunctionType type, TArgument argument) { int id = this.CreateId(); var queue = new WaitQueue <ResponseInfo>(); _queueMap.Add(id, queue); var messageStream = new RecyclableMemoryStream(_bufferManager); var writer = new MessageStreamWriter(messageStream, _bufferManager); writer.Write((ulong)type); writer.Write((ulong)id); Stream valueStream = null; if (argument != null) { try { valueStream = new RecyclableMemoryStream(_bufferManager); JsonUtils.Save(valueStream, argument); } catch (Exception) { if (valueStream != null) { valueStream.Dispose(); valueStream = null; } throw; } } messageStream.Seek(0, SeekOrigin.Begin); _messagingManager.Send(new UniteStream(messageStream, valueStream)); return(id, queue); }