1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
//------------------------------------------------------------------------------
// <copyright file="HttpAsyncResult.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
/*
* ASP.NET simple internal implementation of IAsyncResult
*
* Copyright (c) 2000 Microsoft Corporation
*/
namespace System.Web {
using System;
using System.Threading;
using System.Web.Util;
internal class HttpAsyncResult : IAsyncResult {
private AsyncCallback _callback;
private Object _asyncState;
private bool _completed;
private bool _completedSynchronously;
private Object _result;
private Exception _error;
private Thread _threadWhichStartedOperation;
// pipeline support
private RequestNotificationStatus
_status;
/*
* Constructor with pending result
*/
internal HttpAsyncResult(AsyncCallback cb, Object state) {
_callback = cb;
_asyncState = state;
_status = RequestNotificationStatus.Continue;
}
/*
* Constructor with known result
*/
internal HttpAsyncResult(AsyncCallback cb, Object state,
bool completed, Object result, Exception error) {
_callback = cb;
_asyncState = state;
_completed = completed;
_completedSynchronously = completed;
_result = result;
_error = error;
_status = RequestNotificationStatus.Continue;
if (_completed && _callback != null)
_callback(this);
}
internal void SetComplete() {
_completed = true;
}
/*
* Helper method to process completions
*/
internal void Complete(bool synchronous, Object result, Exception error, RequestNotificationStatus status) {
if (Volatile.Read(ref _threadWhichStartedOperation) == Thread.CurrentThread) {
// If we're calling Complete on the same thread which kicked off the operation, then
// we ignore the 'synchronous' value that the caller provided to us since we know
// for a fact that this is really a synchronous completion. This is only checked if
// the caller calls the MarkCallToBeginMethod* routines below.
synchronous = true;
}
_completed = true;
_completedSynchronously = synchronous;
_result = result;
_error = error;
_status = status;
if (_callback != null)
_callback(this);
}
internal void Complete(bool synchronous, Object result, Exception error) {
Complete(synchronous, result, error, RequestNotificationStatus.Continue);
}
/*
* Helper method to implement End call to async method
*/
internal Object End() {
if (_error != null)
throw new HttpException(null, _error);
return _result;
}
// If the caller needs to invoke an asynchronous method where the only way of knowing whether the
// method actually completed synchronously is to inspect which thread the callback was invoked on,
// then the caller should surround the asynchronous call with calls to the below Started / Completed
// methods. The callback can compare the captured thread against the current thread to see if the
// completion was synchronous. The caller calls the Completed method when unwinding so that the
// captured thread can be cleared out, preventing an asynchronous invocation on the same thread
// from being mistaken for a synchronous invocation.
internal void MarkCallToBeginMethodStarted() {
Thread originalThread = Interlocked.CompareExchange(ref _threadWhichStartedOperation, Thread.CurrentThread, null);
Debug.Assert(originalThread == null, "Another thread already called MarkCallToBeginMethodStarted.");
}
internal void MarkCallToBeginMethodCompleted() {
Thread originalThread = Interlocked.Exchange(ref _threadWhichStartedOperation, null);
Debug.Assert(originalThread == Thread.CurrentThread, "This thread did not call MarkCallToBeginMethodStarted.");
}
//
// Properties that are not part of IAsyncResult
//
internal Exception Error { get { return _error;}}
internal RequestNotificationStatus Status {
get {
return _status;
}
}
//
// IAsyncResult implementation
//
public bool IsCompleted { get { return _completed;}}
public bool CompletedSynchronously { get { return _completedSynchronously;}}
public Object AsyncState { get { return _asyncState;}}
public WaitHandle AsyncWaitHandle { get { return null;}} // wait not supported
}
}
|