You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@@ -0,0 +1,289 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.IdentityModel
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Runtime;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for common AsyncResult programming scenarios.
|
||||
/// </summary>
|
||||
public abstract class AsyncResult : IAsyncResult, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// End should be called when the End function for the asynchronous operation is complete. It
|
||||
/// ensures the asynchronous operation is complete, and does some common validation.
|
||||
/// </summary>
|
||||
/// <param name="result">The <see cref="IAsyncResult"/> representing the status of an asynchronous operation.</param>
|
||||
public static void End(IAsyncResult result)
|
||||
{
|
||||
if (result == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result");
|
||||
|
||||
AsyncResult asyncResult = result as AsyncResult;
|
||||
|
||||
if (asyncResult == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ID4001), "result"));
|
||||
|
||||
if (asyncResult.endCalled)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ID4002)));
|
||||
|
||||
asyncResult.endCalled = true;
|
||||
|
||||
if (!asyncResult.completed)
|
||||
asyncResult.AsyncWaitHandle.WaitOne();
|
||||
|
||||
if (asyncResult.resetEvent != null)
|
||||
((IDisposable)asyncResult.resetEvent).Dispose();
|
||||
|
||||
if (asyncResult.exception != null)
|
||||
throw asyncResult.exception;
|
||||
}
|
||||
|
||||
AsyncCallback callback;
|
||||
bool completed;
|
||||
bool completedSync;
|
||||
bool disposed;
|
||||
bool endCalled;
|
||||
Exception exception;
|
||||
ManualResetEvent resetEvent;
|
||||
object state;
|
||||
|
||||
object thisLock;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for async results that do not need a callback or state.
|
||||
/// </summary>
|
||||
protected AsyncResult()
|
||||
: this(null, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for async results that do not need a callback.
|
||||
/// </summary>
|
||||
/// <param name="state">A user-defined object that qualifies or contains information about an asynchronous operation.</param>
|
||||
protected AsyncResult(object state)
|
||||
: this(null, state)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for async results that need a callback and a state.
|
||||
/// </summary>
|
||||
/// <param name="callback">The method to be called 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)
|
||||
{
|
||||
this.thisLock = new object();
|
||||
this.callback = callback;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalizer for AsyncResult.
|
||||
/// </summary>
|
||||
~AsyncResult()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this version of complete when your asynchronous operation is complete. This will update the state
|
||||
/// of the operation and notify the callback.
|
||||
/// </summary>
|
||||
/// <param name="completedSynchronously">True if the asynchronous operation completed synchronously.</param>
|
||||
protected void Complete(bool completedSynchronously)
|
||||
{
|
||||
Complete(completedSynchronously, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this version of complete if you raise an exception during processing. In addition to notifying
|
||||
/// the callback, it will capture the exception and store it to be thrown during AsyncResult.End.
|
||||
/// </summary>
|
||||
/// <param name="completedSynchronously">True if the asynchronous operation completed synchronously.</param>
|
||||
/// <param name="exception">The exception during the processing of the asynchronous operation.</param>
|
||||
protected void Complete(bool completedSynchronously, Exception exception)
|
||||
{
|
||||
if (completed == true)
|
||||
{
|
||||
// it is a bug to call complete twice
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new AsynchronousOperationException(SR.GetString(SR.ID4005)));
|
||||
}
|
||||
|
||||
completedSync = completedSynchronously;
|
||||
this.exception = exception;
|
||||
|
||||
if (completedSynchronously)
|
||||
{
|
||||
//
|
||||
// No event should be set for synchronous completion
|
||||
//
|
||||
completed = true;
|
||||
Fx.Assert(resetEvent == null, SR.GetString(SR.ID8025));
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Complete asynchronously
|
||||
//
|
||||
lock (thisLock)
|
||||
{
|
||||
completed = true;
|
||||
if (resetEvent != null)
|
||||
resetEvent.Set();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// finally call the call back. Note, we are expecting user's callback to handle the exception
|
||||
// so, if the callback throw exception, all we can do is burn and crash.
|
||||
//
|
||||
try
|
||||
{
|
||||
if (callback != null)
|
||||
callback(this);
|
||||
}
|
||||
catch (ThreadAbortException)
|
||||
{
|
||||
//
|
||||
// The thread running the callback is being aborted. We ignore this case.
|
||||
//
|
||||
}
|
||||
catch (AsynchronousOperationException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
#pragma warning suppress 56500
|
||||
catch (Exception unhandledException)
|
||||
{
|
||||
//
|
||||
// The callback raising an exception is equivalent to Main raising an exception w/out a catch.
|
||||
// We should just throw it back. We should log the exception somewhere.
|
||||
//
|
||||
// Because the stack trace gets lost on a rethrow, we're wrapping it in a generic exception
|
||||
// so the stack trace is preserved.
|
||||
//
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new AsynchronousOperationException(SR.GetString(SR.ID4003), unhandledException));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes of unmanaged resources held by the AsyncResult.
|
||||
/// </summary>
|
||||
/// <param name="isExplicitDispose">True if this is an explicit call to Dispose.</param>
|
||||
protected virtual void Dispose(bool isExplicitDispose)
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
if (isExplicitDispose)
|
||||
{
|
||||
lock (thisLock)
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
//
|
||||
// Mark disposed
|
||||
//
|
||||
disposed = true;
|
||||
|
||||
//
|
||||
// Called explicitly to close the object
|
||||
//
|
||||
if (resetEvent != null)
|
||||
resetEvent.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Called for finalization
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region IAsyncResult implementation
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user-defined state information that was passed to the Begin method.
|
||||
/// </summary>
|
||||
public object AsyncState
|
||||
{
|
||||
get
|
||||
{
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the wait handle of the async event.
|
||||
/// </summary>
|
||||
public virtual WaitHandle AsyncWaitHandle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (resetEvent == null)
|
||||
{
|
||||
bool savedCompleted = completed;
|
||||
|
||||
lock (thisLock)
|
||||
{
|
||||
if (resetEvent == null)
|
||||
resetEvent = new ManualResetEvent(completed);
|
||||
}
|
||||
|
||||
if (!savedCompleted && completed)
|
||||
resetEvent.Set();
|
||||
}
|
||||
|
||||
return resetEvent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that indicates whether the asynchronous operation completed synchronously.
|
||||
/// </summary>
|
||||
public bool CompletedSynchronously
|
||||
{
|
||||
get
|
||||
{
|
||||
return completedSync;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that indicates whether the asynchronous operation has completed.
|
||||
/// </summary>
|
||||
public bool IsCompleted
|
||||
{
|
||||
get
|
||||
{
|
||||
return completed;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Disposes this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user