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