예제 #1
0
        /// <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);
        }
예제 #2
0
 /// <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."));
 }