@@ -97,7 +97,7 @@ public void GetResult()
9797}
9898
9999/// <summary>
100- /// Represents awaitable object that can suspend exception raised by the underlying task.
100+ /// Represents awaitable object that can suspend the exception raised by the underlying task.
101101/// </summary>
102102/// <typeparam name="TArg">The type of the argument to be passed to the exception filter.</typeparam>
103103[ StructLayout ( LayoutKind . Auto ) ]
@@ -187,4 +187,80 @@ public void GetResult()
187187 }
188188 }
189189 }
190+ }
191+
192+ /// <summary>
193+ /// Represents awaitable object that can suspend the exception raised by the underlying task.
194+ /// </summary>
195+ /// <typeparam name="T">The type of the task.</typeparam>
196+ [ StructLayout ( LayoutKind . Auto ) ]
197+ public readonly struct AwaitableResult < T >
198+ {
199+ private readonly Task < T > task ;
200+
201+ internal AwaitableResult ( Task < T > task ) => this . task = task ;
202+
203+ internal bool ContinueOnCapturedContext
204+ {
205+ get ;
206+ init ;
207+ }
208+
209+ /// <summary>
210+ /// Configures an awaiter for this value.
211+ /// </summary>
212+ /// <param name="continueOnCapturedContext">
213+ /// <see langword="true"/> to attempt to marshal the continuation back to the captured context;
214+ /// otherwise, <see langword="false"/>.
215+ /// </param>
216+ /// <returns>The configured object.</returns>
217+ public AwaitableResult < T > ConfigureAwait ( bool continueOnCapturedContext )
218+ => this with { ContinueOnCapturedContext = continueOnCapturedContext } ;
219+
220+ /// <summary>
221+ /// Gets the awaiter for this object.
222+ /// </summary>
223+ /// <returns>The awaiter for this object.</returns>
224+ public Awaiter GetAwaiter ( ) => new ( task , ContinueOnCapturedContext ) ;
225+
226+ /// <summary>
227+ /// Represents the awaiter that suspends exception.
228+ /// </summary>
229+ [ StructLayout ( LayoutKind . Auto ) ]
230+ public readonly struct Awaiter : ICriticalNotifyCompletion
231+ {
232+ private readonly ConfiguredTaskAwaitable < T > . ConfiguredTaskAwaiter awaiter ;
233+
234+ internal Awaiter ( Task < T > task , bool continueOnCapturedContext )
235+ => awaiter = task . ConfigureAwait ( continueOnCapturedContext ) . GetAwaiter ( ) ;
236+
237+ /// <summary>
238+ /// Gets a value indicating that <see cref="AwaitableResult{T}"/> has completed.
239+ /// </summary>
240+ public bool IsCompleted => awaiter . IsCompleted ;
241+
242+ /// <inheritdoc/>
243+ public void OnCompleted ( Action action ) => awaiter . OnCompleted ( action ) ;
244+
245+ /// <inheritdoc/>
246+ public void UnsafeOnCompleted ( Action action ) => awaiter . UnsafeOnCompleted ( action ) ;
247+
248+ /// <summary>
249+ /// Obtains a result of asynchronous operation, and suspends exception if needed.
250+ /// </summary>
251+ public Result < T > GetResult ( )
252+ {
253+ Result < T > result ;
254+ try
255+ {
256+ result = new ( awaiter . GetResult ( ) ) ;
257+ }
258+ catch ( Exception e )
259+ {
260+ result = new ( e ) ;
261+ }
262+
263+ return result ;
264+ }
265+ }
190266}
0 commit comments