1 #region Copyright notice and license 2 3 // Copyright 2015 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 #endregion 18 19 using System; 20 using System.Runtime.CompilerServices; 21 using System.Threading.Tasks; 22 23 namespace Grpc.Core 24 { 25 /// <summary> 26 /// Return type for single request - single response call. 27 /// </summary> 28 /// <typeparam name="TResponse">Response message type for this call.</typeparam> 29 public sealed class AsyncUnaryCall<TResponse> : IDisposable 30 { 31 readonly Task<TResponse> responseAsync; 32 readonly AsyncCallState callState; 33 34 35 /// <summary> 36 /// Creates a new AsyncUnaryCall object with the specified properties. 37 /// </summary> 38 /// <param name="responseAsync">The response of the asynchronous call.</param> 39 /// <param name="responseHeadersAsync">Response headers of the asynchronous call.</param> 40 /// <param name="getStatusFunc">Delegate returning the status of the call.</param> 41 /// <param name="getTrailersFunc">Delegate returning the trailing metadata of the call.</param> 42 /// <param name="disposeAction">Delegate to invoke when Dispose is called on the call object.</param> AsyncUnaryCall(Task<TResponse> responseAsync, Task<Metadata> responseHeadersAsync, Func<Status> getStatusFunc, Func<Metadata> getTrailersFunc, Action disposeAction)43 public AsyncUnaryCall(Task<TResponse> responseAsync, 44 Task<Metadata> responseHeadersAsync, 45 Func<Status> getStatusFunc, 46 Func<Metadata> getTrailersFunc, 47 Action disposeAction) 48 { 49 this.responseAsync = responseAsync; 50 this.callState = new AsyncCallState(responseHeadersAsync, getStatusFunc, getTrailersFunc, disposeAction); 51 } 52 53 /// <summary> 54 /// Creates a new AsyncUnaryCall object with the specified properties. 55 /// </summary> 56 /// <param name="responseAsync">The response of the asynchronous call.</param> 57 /// <param name="responseHeadersAsync">Response headers of the asynchronous call.</param> 58 /// <param name="getStatusFunc">Delegate returning the status of the call.</param> 59 /// <param name="getTrailersFunc">Delegate returning the trailing metadata of the call.</param> 60 /// <param name="disposeAction">Delegate to invoke when Dispose is called on the call object.</param> 61 /// <param name="state">State object for use with the callback parameters.</param> AsyncUnaryCall(Task<TResponse> responseAsync, Func<object, Task<Metadata>> responseHeadersAsync, Func<object, Status> getStatusFunc, Func<object, Metadata> getTrailersFunc, Action<object> disposeAction, object state)62 public AsyncUnaryCall(Task<TResponse> responseAsync, 63 Func<object, Task<Metadata>> responseHeadersAsync, 64 Func<object, Status> getStatusFunc, 65 Func<object, Metadata> getTrailersFunc, 66 Action<object> disposeAction, 67 object state) 68 { 69 this.responseAsync = responseAsync; 70 callState = new AsyncCallState(responseHeadersAsync, getStatusFunc, getTrailersFunc, disposeAction, state); 71 } 72 73 /// <summary> 74 /// Asynchronous call result. 75 /// </summary> 76 public Task<TResponse> ResponseAsync 77 { 78 get 79 { 80 return this.responseAsync; 81 } 82 } 83 84 /// <summary> 85 /// Asynchronous access to response headers. 86 /// </summary> 87 public Task<Metadata> ResponseHeadersAsync 88 { 89 get 90 { 91 return callState.ResponseHeadersAsync(); 92 } 93 } 94 95 /// <summary> 96 /// Allows awaiting this object directly. 97 /// </summary> GetAwaiter()98 public TaskAwaiter<TResponse> GetAwaiter() 99 { 100 return responseAsync.GetAwaiter(); 101 } 102 103 /// <summary> 104 /// Gets the call status if the call has already finished. 105 /// Throws InvalidOperationException otherwise. 106 /// </summary> GetStatus()107 public Status GetStatus() 108 { 109 return callState.GetStatus(); 110 } 111 112 /// <summary> 113 /// Gets the call trailing metadata if the call has already finished. 114 /// Throws InvalidOperationException otherwise. 115 /// </summary> GetTrailers()116 public Metadata GetTrailers() 117 { 118 return callState.GetTrailers(); 119 } 120 121 /// <summary> 122 /// Provides means to cleanup after the call. 123 /// If the call has already finished normally (request stream has been completed and call result has been received), doesn't do anything. 124 /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call. 125 /// As a result, all resources being used by the call should be released eventually. 126 /// </summary> 127 /// <remarks> 128 /// Normally, there is no need for you to dispose the call unless you want to utilize the 129 /// "Cancel" semantics of invoking <c>Dispose</c>. 130 /// </remarks> Dispose()131 public void Dispose() 132 { 133 callState.Dispose(); 134 } 135 } 136 } 137