f59989655ec5a1099b60d08a82781717527c8889
[platform/upstream/grpc.git] / src / csharp / Grpc.Core / AsyncClientStreamingCall.cs
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 client streaming calls.
27     /// </summary>
28     /// <typeparam name="TRequest">Request message type for this call.</typeparam>
29     /// <typeparam name="TResponse">Response message type for this call.</typeparam>
30     public sealed class AsyncClientStreamingCall<TRequest, TResponse> : IDisposable
31     {
32         readonly IClientStreamWriter<TRequest> requestStream;
33         readonly Task<TResponse> responseAsync;
34         readonly Task<Metadata> responseHeadersAsync;
35         readonly Func<Status> getStatusFunc;
36         readonly Func<Metadata> getTrailersFunc;
37         readonly Action disposeAction;
38
39         /// <summary>
40         /// Creates a new AsyncClientStreamingCall object with the specified properties.
41         /// </summary>
42         /// <param name="requestStream">Stream of request values.</param>
43         /// <param name="responseAsync">The response of the asynchronous call.</param>
44         /// <param name="responseHeadersAsync">Response headers of the asynchronous call.</param>
45         /// <param name="getStatusFunc">Delegate returning the status of the call.</param>
46         /// <param name="getTrailersFunc">Delegate returning the trailing metadata of the call.</param>
47         /// <param name="disposeAction">Delegate to invoke when Dispose is called on the call object.</param>
48         public AsyncClientStreamingCall(IClientStreamWriter<TRequest> requestStream,
49                                         Task<TResponse> responseAsync,
50                                         Task<Metadata> responseHeadersAsync,
51                                         Func<Status> getStatusFunc,
52                                         Func<Metadata> getTrailersFunc,
53                                         Action disposeAction)
54         {
55             this.requestStream = requestStream;
56             this.responseAsync = responseAsync;
57             this.responseHeadersAsync = responseHeadersAsync;
58             this.getStatusFunc = getStatusFunc;
59             this.getTrailersFunc = getTrailersFunc;
60             this.disposeAction = disposeAction;
61         }
62
63         /// <summary>
64         /// Asynchronous call result.
65         /// </summary>
66         public Task<TResponse> ResponseAsync
67         {
68             get
69             {
70                 return this.responseAsync;
71             }
72         }
73
74         /// <summary>
75         /// Asynchronous access to response headers.
76         /// </summary>
77         public Task<Metadata> ResponseHeadersAsync
78         {
79             get
80             {
81                 return this.responseHeadersAsync;
82             }
83         }
84
85         /// <summary>
86         /// Async stream to send streaming requests.
87         /// </summary>
88         public IClientStreamWriter<TRequest> RequestStream
89         {
90             get
91             {
92                 return requestStream;
93             }
94         }
95
96         /// <summary>
97         /// Allows awaiting this object directly.
98         /// </summary>
99         /// <returns></returns>
100         public TaskAwaiter<TResponse> GetAwaiter()
101         {
102             return responseAsync.GetAwaiter();
103         }
104
105         /// <summary>
106         /// Gets the call status if the call has already finished.
107         /// Throws InvalidOperationException otherwise.
108         /// </summary>
109         public Status GetStatus()
110         {
111             return getStatusFunc();
112         }
113
114         /// <summary>
115         /// Gets the call trailing metadata if the call has already finished.
116         /// Throws InvalidOperationException otherwise.
117         /// </summary>
118         public Metadata GetTrailers()
119         {
120             return getTrailersFunc();
121         }
122
123         /// <summary>
124         /// Provides means to cleanup after the call.
125         /// If the call has already finished normally (request stream has been completed and call result has been received), doesn't do anything.
126         /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
127         /// As a result, all resources being used by the call should be released eventually.
128         /// </summary>
129         /// <remarks>
130         /// Normally, there is no need for you to dispose the call unless you want to utilize the
131         /// "Cancel" semantics of invoking <c>Dispose</c>.
132         /// </remarks>
133         public void Dispose()
134         {
135             disposeAction.Invoke();
136         }
137     }
138 }