internal void InternalComplete(Exception exception, bool completedSynchronously) { this.exception = exception; this.completedSynchronously = completedSynchronously; EventWaitHandle eventWaitHandle = Interlocked.CompareExchange <EventWaitHandle>(ref this.waitHandle, AsyncResultBase.completeWaitHandleSentinel, null); if (AsyncResultBase.completeWaitHandleSentinel == eventWaitHandle) { AsyncCallTracker asyncState = this.AsyncState as AsyncCallTracker; string str = (asyncState == null ? "" : string.Concat("Trace: ", asyncState.GetCallStack())); throw new InvalidOperationException(string.Concat("Async operation ", this.MethodName, " completed twice. ", str)); } if (eventWaitHandle != null) { if (eventWaitHandle.WaitOne(0, false)) { AsyncCallTracker asyncCallTracker = this.AsyncState as AsyncCallTracker; string str1 = (asyncCallTracker == null ? "" : string.Concat("Trace: ", asyncCallTracker.GetCallStack())); throw new InvalidOperationException(string.Concat("Async operation ", this.MethodName, " completed twice. ", str1)); } eventWaitHandle.Set(); } AsyncCallback asyncCallback = this.callback; if (asyncCallback != null) { this.callback = null; asyncCallback(this); } }
public static void StaticTraceData(TraceEventCache eventCache, string source, TraceEventType eventType, object data) { AsyncCallTrackingTraceListener.AsyncIteratorState asyncIteratorState; if (source != "AsyncHelper") { return; } AsyncIteratorContextBase asyncIteratorContextBase = data as AsyncIteratorContextBase; TraceEventType traceEventType = eventType; if (traceEventType <= TraceEventType.Stop) { if (traceEventType == TraceEventType.Start) { lock (AsyncCallTrackingTraceListener.iterators) { asyncIteratorState = new AsyncCallTrackingTraceListener.AsyncIteratorState() { Iterator = asyncIteratorContextBase, ThreadId = eventCache.ThreadId }; AsyncCallTrackingTraceListener.iterators.Add(asyncIteratorState.Iterator, asyncIteratorState); } } else { if (traceEventType != TraceEventType.Stop) { return; } lock (AsyncCallTrackingTraceListener.iterators) { AsyncCallTrackingTraceListener.iterators.Remove(asyncIteratorContextBase); } } } else if (traceEventType == TraceEventType.Suspend) { lock (AsyncCallTrackingTraceListener.iterators) { AsyncCallTracker asyncCallTracker = (AsyncCallTracker)data; asyncIteratorState = AsyncCallTrackingTraceListener.iterators[asyncCallTracker.Caller]; asyncIteratorState.Call = asyncCallTracker; asyncIteratorState.SuspendedTime = DateTime.UtcNow; } } else { if (traceEventType != TraceEventType.Resume) { return; } lock (AsyncCallTrackingTraceListener.iterators) { asyncIteratorState = AsyncCallTrackingTraceListener.iterators[asyncIteratorContextBase]; asyncIteratorState.Call = null; asyncIteratorState.ThreadId = eventCache.ThreadId; } } }
internal string GetCallStack() { StringBuilder stringBuilder = new StringBuilder(); for (AsyncCallTracker i = this; i != null; i = i.caller.Caller) { stringBuilder.AppendFormat("from {0} to {1}\n", i.caller.MethodName, i.calleeName); } return(stringBuilder.ToString()); }
private void ExecuteIterator(bool inBegin) { Exception exception = null; try { if (!inBegin) { Tracing.TraceSource.TraceData(TraceEventType.Resume, 0, this); } else { Tracing.TraceSource.TraceData(TraceEventType.Start, 0, this); } while (this.iterator.MoveNext()) { AsyncCallTracker asyncCallTracker = this.TrackerFromAsyncResult(this.iterator.Current); Tracing.TraceSource.TraceData(TraceEventType.Suspend, 0, asyncCallTracker); if (!asyncCallTracker.Wait()) { return; } else { Tracing.TraceSource.TraceData(TraceEventType.Resume, 0, this); } } } catch (Exception exception1) { exception = exception1; } try { try { this.iterator.Dispose(); } catch (Exception exception2) { exception = exception2; } } finally { this.iterator = null; } Tracing.TraceSource.TraceEvent(TraceEventType.Stop, 0, base.MethodName); base.InternalComplete(exception, inBegin); }
private static void BuildCallTree(Stream stream) { List <AsyncCallTrackingTraceListener.AsyncIteratorState> asyncIteratorStates; AsyncCallTrackingTraceListener.AsyncIteratorState asyncIteratorState; List <AsyncCallTrackingTraceListener.AsyncIteratorState> asyncIteratorStates1 = new List <AsyncCallTrackingTraceListener.AsyncIteratorState>(); Dictionary <AsyncCallTrackingTraceListener.AsyncIteratorState, List <AsyncCallTrackingTraceListener.AsyncIteratorState> > asyncIteratorStates2 = new Dictionary <AsyncCallTrackingTraceListener.AsyncIteratorState, List <AsyncCallTrackingTraceListener.AsyncIteratorState> >(); lock (AsyncCallTrackingTraceListener.iterators) { DateTime utcNow = DateTime.UtcNow; foreach (AsyncCallTrackingTraceListener.AsyncIteratorState value in AsyncCallTrackingTraceListener.iterators.Values) { AsyncCallTracker caller = value.Iterator.Caller; if (caller != null) { if (!AsyncCallTrackingTraceListener.iterators.TryGetValue(caller.Caller, out asyncIteratorState)) { continue; } if (!asyncIteratorStates2.TryGetValue(asyncIteratorState, out asyncIteratorStates)) { asyncIteratorStates = new List <AsyncCallTrackingTraceListener.AsyncIteratorState>(1); asyncIteratorStates2.Add(asyncIteratorState, asyncIteratorStates); } asyncIteratorStates.Add(value); } else { asyncIteratorStates1.Add(value); } } using (XmlTextWriter xmlTextWriter = new XmlTextWriter(stream, Encoding.UTF8)) { xmlTextWriter.Formatting = Formatting.Indented; xmlTextWriter.WriteStartDocument(); xmlTextWriter.WriteStartElement("callTree"); xmlTextWriter.WriteStartAttribute("time"); xmlTextWriter.WriteValue(utcNow); xmlTextWriter.WriteEndAttribute(); foreach (AsyncCallTrackingTraceListener.AsyncIteratorState asyncIteratorState1 in asyncIteratorStates1) { AsyncCallTrackingTraceListener.AppendCallTree(utcNow, xmlTextWriter, asyncIteratorState1, asyncIteratorStates2); } xmlTextWriter.WriteEndElement(); xmlTextWriter.WriteEndDocument(); } } }
private AsyncCallTracker TrackerFromAsyncResult(IAsyncResult asyncResult) { AsyncCallTracker asyncState = asyncResult.AsyncState as AsyncCallTracker; if (asyncState == null) { throw new InvalidOperationException(string.Concat("Async iterator ", base.MethodName, " made an async call without passing the result of AsyncIteratorContext.ResumeContext as the call's state parameter.")); } if (!object.ReferenceEquals(asyncState.Caller, this)) { string[] methodName = new string[] { "Async iterator ", base.MethodName, " made an async call to ", asyncState.CalleeName, " using an async state that was not generated by the associated AsyncIteratorContext object." }; throw new InvalidOperationException(string.Concat(methodName)); } return(asyncState); }