e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
130 lines
3.8 KiB
C#
130 lines
3.8 KiB
C#
// <copyright>
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
|
|
namespace System.Runtime
|
|
{
|
|
using System.Diagnostics;
|
|
|
|
[Fx.Tag.SynchronizationPrimitive(Fx.Tag.BlocksUsing.NonBlocking, SupportsAsync = true, ReleaseMethod = "Complete")]
|
|
abstract class AsyncEventArgs : IAsyncEventArgs
|
|
{
|
|
#if DEBUG
|
|
StackTrace startStack;
|
|
StackTrace completeStack;
|
|
#endif
|
|
OperationState state;
|
|
object asyncState;
|
|
AsyncEventArgsCallback callback;
|
|
Exception exception;
|
|
|
|
public Exception Exception
|
|
{
|
|
get { return this.exception; }
|
|
}
|
|
|
|
public object AsyncState
|
|
{
|
|
get { return this.asyncState; }
|
|
}
|
|
|
|
OperationState State
|
|
{
|
|
set
|
|
{
|
|
switch (value)
|
|
{
|
|
case OperationState.PendingCompletion:
|
|
if (this.state == OperationState.PendingCompletion)
|
|
{
|
|
throw Fx.Exception.AsError(new InvalidOperationException(InternalSR.AsyncEventArgsCompletionPending(GetType())));
|
|
}
|
|
#if DEBUG
|
|
if (!Fx.FastDebug)
|
|
{
|
|
this.startStack = new StackTrace();
|
|
}
|
|
#endif
|
|
break;
|
|
case OperationState.CompletedAsynchronously:
|
|
case OperationState.CompletedSynchronously:
|
|
if (this.state != OperationState.PendingCompletion)
|
|
{
|
|
throw Fx.Exception.AsError(new InvalidOperationException(InternalSR.AsyncEventArgsCompletedTwice(GetType())));
|
|
}
|
|
#if DEBUG
|
|
if (!Fx.FastDebug)
|
|
{
|
|
this.completeStack = new StackTrace();
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
this.state = value;
|
|
}
|
|
}
|
|
|
|
public void Complete(bool completedSynchronously)
|
|
{
|
|
this.Complete(completedSynchronously, null);
|
|
}
|
|
|
|
public virtual void Complete(bool completedSynchronously, Exception exception)
|
|
{
|
|
// The callback will be invoked only if completedSynchronously is false.
|
|
// It is the responsibility of the caller or callback to throw the exception.
|
|
this.exception = exception;
|
|
if (completedSynchronously)
|
|
{
|
|
this.State = OperationState.CompletedSynchronously;
|
|
}
|
|
else
|
|
{
|
|
this.State = OperationState.CompletedAsynchronously;
|
|
this.callback(this);
|
|
}
|
|
}
|
|
|
|
protected void SetAsyncState(AsyncEventArgsCallback callback, object state)
|
|
{
|
|
if (callback == null)
|
|
{
|
|
throw Fx.Exception.ArgumentNull("callback");
|
|
}
|
|
|
|
this.State = OperationState.PendingCompletion;
|
|
this.asyncState = state;
|
|
this.callback = callback;
|
|
}
|
|
|
|
enum OperationState
|
|
{
|
|
Created,
|
|
PendingCompletion,
|
|
CompletedSynchronously,
|
|
CompletedAsynchronously,
|
|
}
|
|
}
|
|
|
|
class AsyncEventArgs<TArgument> : AsyncEventArgs
|
|
{
|
|
public TArgument Arguments
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public virtual void Set(AsyncEventArgsCallback callback, TArgument arguments, object state)
|
|
{
|
|
this.SetAsyncState(callback, state);
|
|
this.Arguments = arguments;
|
|
}
|
|
}
|
|
|
|
class AsyncEventArgs<TArgument, TResult> : AsyncEventArgs<TArgument>
|
|
{
|
|
public TResult Result { get; set; }
|
|
}
|
|
}
|