/// <summary> /// This method implements <see cref="AsyncDataColumn.TryGetValueAsync"/> method. /// </summary> /// <returns>A task which will on completion contain <see cref="ResultOrNone{TResult}"/> struct describing the data.</returns> /// <seealso cref="ResultOrNone{TResult}"/> /// <remarks> /// If value reading has already been started by <see cref="ReadBytesAsync(Byte[], Int32, Int32)"/> method and not yet finished, this method will return <see cref="ResultOrNone{TResult}"/> such that its <see cref="ResultOrNone{TResult}.HasResult"/> property is <c>false</c>. /// </remarks> public async ValueTask <ResultOrNone <Object> > TryGetValueAsync() { Int32 oldState; ResultOrNone <Object> retVal; if ((oldState = Interlocked.CompareExchange(ref this._state, READING_WHOLE_VALUE, INITIAL)) > COMPLETE) { // Either concurrent/re-entrant attempt, or reading by bytes has started, or faulted retVal = new ResultOrNone <Object>(); } else { if (oldState == INITIAL) { // First-time acquisition var faulted = true; try { Interlocked.Exchange(ref this._value, await this.PerformReadAsValueAsync()); faulted = false; } catch { Interlocked.Exchange(ref this._state, FAULTED); throw; } finally { if (!faulted) { Interlocked.Exchange(ref this._state, COMPLETE); } } } retVal = this._state == FAULTED ? default : new ResultOrNone <Object>(this._value); } return(retVal); }
/// <summary> /// Gets the result from <see cref="ResultOrNone{TResult}"/>, or throws it it doesn't have a result. /// </summary> /// <typeparam name="T">The type of the result.</typeparam> /// <param name="resultOrNone">The <see cref="ResultOrNone{TResult}"/>.</param> /// <returns>The result of this <see cref="ResultOrNone{TResult}"/>, if it has one.</returns> /// <exception cref="InvalidOperationException">If this <see cref="ResultOrNone{TResult}"/> does not have a result (its <see cref="ResultOrNone{TResult}.HasResult"/> property is <c>false</c>).</exception> public static T GetResultOrThrow <T>(this ResultOrNone <T> resultOrNone) { return(resultOrNone.HasResult ? resultOrNone.Result : throw new InvalidOperationException("Result is not available.")); }