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.Threading.Tasks; 21 22 namespace Grpc.Core 23 { 24 /// <summary> 25 /// Return type for server streaming calls. 26 /// </summary> 27 /// <typeparam name="TResponse">Response message type for this call.</typeparam> 28 public sealed class AsyncServerStreamingCall<TResponse> : IDisposable 29 { 30 readonly IAsyncStreamReader<TResponse> responseStream; 31 readonly AsyncCallState callState; 32 33 /// <summary> 34 /// Creates a new AsyncDuplexStreamingCall object with the specified properties. 35 /// </summary> 36 /// <param name="responseStream">Stream of response values.</param> 37 /// <param name="responseHeadersAsync">Response headers of the asynchronous call.</param> 38 /// <param name="getStatusFunc">Delegate returning the status of the call.</param> 39 /// <param name="getTrailersFunc">Delegate returning the trailing metadata of the call.</param> 40 /// <param name="disposeAction">Delegate to invoke when Dispose is called on the call object.</param> AsyncServerStreamingCall(IAsyncStreamReader<TResponse> responseStream, Task<Metadata> responseHeadersAsync, Func<Status> getStatusFunc, Func<Metadata> getTrailersFunc, Action disposeAction)41 public AsyncServerStreamingCall(IAsyncStreamReader<TResponse> responseStream, 42 Task<Metadata> responseHeadersAsync, 43 Func<Status> getStatusFunc, 44 Func<Metadata> getTrailersFunc, 45 Action disposeAction) 46 { 47 this.responseStream = responseStream; 48 this.callState = new AsyncCallState(responseHeadersAsync, getStatusFunc, getTrailersFunc, disposeAction); 49 } 50 51 /// <summary> 52 /// Creates a new AsyncDuplexStreamingCall object with the specified properties. 53 /// </summary> 54 /// <param name="responseStream">Stream of response values.</param> 55 /// <param name="responseHeadersAsync">Response headers of the asynchronous call.</param> 56 /// <param name="getStatusFunc">Delegate returning the status of the call.</param> 57 /// <param name="getTrailersFunc">Delegate returning the trailing metadata of the call.</param> 58 /// <param name="disposeAction">Delegate to invoke when Dispose is called on the call object.</param> 59 /// <param name="state">State object for use with the callback parameters.</param> AsyncServerStreamingCall(IAsyncStreamReader<TResponse> responseStream, Func<object, Task<Metadata>> responseHeadersAsync, Func<object, Status> getStatusFunc, Func<object, Metadata> getTrailersFunc, Action<object> disposeAction, object state)60 public AsyncServerStreamingCall(IAsyncStreamReader<TResponse> responseStream, 61 Func<object, Task<Metadata>> responseHeadersAsync, 62 Func<object, Status> getStatusFunc, 63 Func<object, Metadata> getTrailersFunc, 64 Action<object> disposeAction, 65 object state) 66 { 67 this.responseStream = responseStream; 68 this.callState = new AsyncCallState(responseHeadersAsync, getStatusFunc, getTrailersFunc, disposeAction, state); 69 } 70 71 /// <summary> 72 /// Async stream to read streaming responses. 73 /// </summary> 74 public IAsyncStreamReader<TResponse> ResponseStream 75 { 76 get 77 { 78 return responseStream; 79 } 80 } 81 82 /// <summary> 83 /// Asynchronous access to response headers. 84 /// </summary> 85 public Task<Metadata> ResponseHeadersAsync 86 { 87 get 88 { 89 return callState.ResponseHeadersAsync(); 90 } 91 } 92 93 /// <summary> 94 /// Gets the call status if the call has already finished. 95 /// Throws InvalidOperationException otherwise. 96 /// </summary> GetStatus()97 public Status GetStatus() 98 { 99 return callState.GetStatus(); 100 } 101 102 /// <summary> 103 /// Gets the call trailing metadata if the call has already finished. 104 /// Throws InvalidOperationException otherwise. 105 /// </summary> GetTrailers()106 public Metadata GetTrailers() 107 { 108 return callState.GetTrailers(); 109 } 110 111 /// <summary> 112 /// Provides means to cleanup after the call. 113 /// If the call has already finished normally (response stream has been fully read), doesn't do anything. 114 /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call. 115 /// As a result, all resources being used by the call should be released eventually. 116 /// </summary> 117 /// <remarks> 118 /// Normally, there is no need for you to dispose the call unless you want to utilize the 119 /// "Cancel" semantics of invoking <c>Dispose</c>. 120 /// </remarks> Dispose()121 public void Dispose() 122 { 123 callState.Dispose(); 124 } 125 } 126 } 127