123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- /*
- * Copyright (C) Alibaba Cloud Computing
- * All rights reserved.
- *
- * 版权所有 (C)阿里云计算有限公司
- */
- using System;
- using System.Diagnostics;
- using System.Threading;
- using Aliyun.OSS.Common.Communication;
- namespace Aliyun.OSS.Util
- {
- /// <summary>
- /// The implementation of <see cref="IAsyncResult"/>
- /// that represents the status of an async operation.
- /// </summary>
- internal abstract class AsyncResult : IAsyncResult, IDisposable
- {
- #region Fields
- private readonly object _asyncState;
- private bool _isCompleted;
- private readonly AsyncCallback _userCallback;
- private ManualResetEvent _asyncWaitEvent;
- private Exception _exception;
- #endregion
- #region IAsyncResult Members
- /// <summary>
- /// Gets a user-defined object that qualifies or contains information about an asynchronous operation.
- /// </summary>
- public object AsyncState
- {
- get { return _asyncState; }
- }
- public AsyncCallback Callback
- {
- get { return _userCallback; }
- }
- /// <summary>
- /// Gets a <see cref="WaitHandle"/> that is used to wait for an asynchronous operation to complete.
- /// </summary>
- public WaitHandle AsyncWaitHandle
- {
- get
- {
- if (_asyncWaitEvent != null)
- return _asyncWaitEvent;
- _asyncWaitEvent = new ManualResetEvent(false);
- if (IsCompleted)
- _asyncWaitEvent.Set();
- return _asyncWaitEvent;
- }
- }
- /// <summary>
- /// Gets a value that indicates whether the asynchronous operation completed synchronously.
- /// </summary>
- public bool CompletedSynchronously { get; protected set; }
- /// <summary>
- /// Gets a value that indicates whether the asynchronous operation has completed.
- /// </summary>
- [DebuggerNonUserCode]
- public bool IsCompleted
- {
- get { return _isCompleted; }
- }
- #endregion
- /// <summary>
- /// Initializes an instance of <see cref="AsyncResult"/>.
- /// </summary>
- /// <param name="callback">The callback method when the async operation completes.</param>
- /// <param name="state">A user-defined object that qualifies or contains information about an asynchronous operation.</param>
- protected AsyncResult(AsyncCallback callback, object state)
- {
- _userCallback = callback;
- _asyncState = state;
- }
- /// <summary>
- /// Completes the async operation with an exception.
- /// </summary>
- /// <param name="ex">Exception from the async operation.</param>
- public void Complete(Exception ex)
- {
- _exception = ex;
- NotifyCompletion();
- }
- /// <summary>
- /// When called in the dervied classes, wait for completion.
- /// It throws exception if the async operation ends with an exception.
- /// </summary>
- protected void WaitForCompletion()
- {
- if (!IsCompleted)
- AsyncWaitHandle.WaitOne();
- if (_exception != null)
- throw _exception;
- }
- /// <summary>
- /// When called in the derived classes, notify operation completion
- /// by setting <see cref="P:AsyncWaitHandle"/> and calling the user callback.
- /// </summary>
- protected void NotifyCompletion()
- {
- _isCompleted = true;
- if (_asyncWaitEvent != null)
- _asyncWaitEvent.Set();
- if (_userCallback != null)
- {
- var httpAsyncResult = this as ServiceClientImpl.HttpAsyncResult;
- Debug.Assert(httpAsyncResult != null);
- _userCallback(httpAsyncResult.AsyncState as RetryableAsyncResult);
- }
- }
- #region IDisposable Members
- /// <summary>
- /// Disposes the object and release resource.
- /// </summary>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- /// <summary>
- /// When overrided in the derived classes, release resources.
- /// </summary>
- /// <param name="disposing">Whether the method is called <see cref="M:Dispose"/></param>
- protected virtual void Dispose(bool disposing)
- {
- if (disposing && _asyncWaitEvent != null)
- {
- _asyncWaitEvent.Close();
- _asyncWaitEvent = null;
- }
- }
- #endregion
- }
- /// <summary>
- /// Represents the status of an async operation.
- /// It also holds the result of the operation.
- /// </summary>
- /// <typeparam name="T">Type of the operation result.</typeparam>
- internal class AsyncResult<T> : AsyncResult
- {
- /// <summary>
- /// The result of the async operation.
- /// </summary>
- private T _result;
- /// <summary>
- /// Initializes an instance of <see cref="AsyncResult<T>"/>.
- /// </summary>
- /// <param name="callback">The callback method when the async operation completes.</param>
- /// <param name="state">A user-defined object that qualifies or contains information about an asynchronous operation.</param>
- public AsyncResult(AsyncCallback callback, object state)
- : base(callback, state)
- { }
- /// <summary>
- /// Gets result and release resources.
- /// </summary>
- /// <returns>The instance of result.</returns>
- public T GetResult()
- {
- base.WaitForCompletion();
- return _result;
- }
- /// <summary>
- /// Sets result and notify completion.
- /// </summary>
- /// <param name="result">The instance of result.</param>
- public void Complete(T result)
- {
- // Complete should not throw if disposed.
- _result = result;
- base.NotifyCompletion();
- }
- }
- }
|