using System;
using System.Diagnostics;
using System.Threading;
namespace Aliyun.Api.LOG.Common
{
///
/// The implementation of
/// that represents the status of an async operation.
///
internal abstract class AsyncResult : IAsyncResult, IDisposable
{
#region Fields
private object _asyncState;
private bool _completedSynchronously;
private bool _isCompleted;
private AsyncCallback _userCallback;
private ManualResetEvent _asyncWaitEvent;
private Exception _exception;
#endregion
#region IAsyncResult Members
///
/// Gets a user-defined object that qualifies or contains information about an asynchronous operation.
///
[DebuggerNonUserCode]
public object AsyncState
{
get
{
return _asyncState;
}
}
///
/// Gets a that is used to wait for an asynchronous operation to complete.
///
[DebuggerNonUserCode]
public WaitHandle AsyncWaitHandle
{
get
{
if (_asyncWaitEvent != null)
{
return _asyncWaitEvent;
}
ManualResetEvent manualResetEvent = new ManualResetEvent(false);
if (Interlocked.CompareExchange(ref _asyncWaitEvent, manualResetEvent, null) != null)
{
manualResetEvent.Close();
}
if (this.IsCompleted)
{
_asyncWaitEvent.Set();
}
return _asyncWaitEvent;
}
}
///
/// Gets a value that indicates whether the asynchronous operation completed synchronously.
///
[DebuggerNonUserCode]
public bool CompletedSynchronously
{
get
{
return _completedSynchronously;
}
protected set
{
_completedSynchronously = value;
}
}
///
/// Gets a value that indicates whether the asynchronous operation has completed.
///
[DebuggerNonUserCode]
public bool IsCompleted
{
get
{
return _isCompleted;
}
}
#endregion
///
/// Initializes an instance of .
///
/// The callback method when the async operation completes.
/// A user-defined object that qualifies or contains information about an asynchronous operation.
protected AsyncResult(AsyncCallback callback, object state)
{
_userCallback = callback;
_asyncState = state;
}
///
/// Completes the async operation with an exception.
///
/// Exception from the async operation.
public void Complete(Exception ex)
{
// Complete should not throw if disposed.
Debug.Assert(ex != null);
_exception = ex;
this.NotifyCompletion();
}
///
/// When called in the dervied classes, wait for completion.
/// It throws exception if the async operation ends with an exception.
///
protected void WaitForCompletion()
{
if (!this.IsCompleted)
{
_asyncWaitEvent.WaitOne();
}
if (this._exception != null)
{
throw this._exception;
}
}
///
/// When called in the derived classes, notify operation completion
/// by setting and calling the user callback.
///
[DebuggerNonUserCode]
protected void NotifyCompletion()
{
_isCompleted = true;
if (_asyncWaitEvent != null)
{
_asyncWaitEvent.Set();
}
if (_userCallback != null)
{
_userCallback(this);
}
}
#region IDisposable Members
///
/// Disposes the object and release resource.
///
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
///
/// When overrided in the derived classes, release resources.
///
/// Whether the method is called
protected virtual void Dispose(bool disposing)
{
if (disposing && _asyncWaitEvent != null)
{
_asyncWaitEvent.Close();
_asyncWaitEvent = null;
}
}
#endregion
}
///
/// Represents the status of an async operation.
/// It also holds the result of the operation.
///
/// Type of the operation result.
internal class AsyncResult : AsyncResult
{
///
/// The result of the async operation.
///
private T _result;
///
/// Initializes an instance of .
///
/// The callback method when the async operation completes.
/// A user-defined object that qualifies or contains information about an asynchronous operation.
public AsyncResult(AsyncCallback callback, object state)
: base(callback, state)
{
}
///
/// Gets result and release resources.
///
/// The instance of result.
public T GetResult()
{
base.WaitForCompletion();
return _result;
}
///
/// Sets result and notify completion.
///
/// The instance of result.
public void Complete(T result)
{
// Complete should not throw if disposed.
this._result = result;
base.NotifyCompletion();
}
}
}