/// <summary> /// Blocks the current thread until the operation completes. /// This is more efficient than calling <b>AsyncWaitHandle.WaitOne()</b> /// since it won't allocate an event if the operation has already /// completed. /// </summary> public void Wait() { #if DEBUG && !MOBILE_DEVICE using (TimedLock.Lock(this)) { if (waitStack == null) { waitStack = CallStack.AsyncTrace(0, true); } if (isWaiting) { Trace("Wait(exception): Another thread is already waiting."); throw new InvalidOperationException("Another thread is already waiting."); } if (isReleased) { Trace("Wait(release): Already released"); return; } if (isCompleted) { isReleased = true; Trace("Wait(no wait): Result={0} Sync={1}", result == null ? "null" : result.ToString(), syncCompletion); return; } isWaiting = true; } #endif #if !MOBILE_DEVICE AsyncTracker.Yield(); #endif #if DEBUG && !MOBILE_DEVICE Trace("Wait(block)"); ((AsyncEvent)this.AsyncWaitHandle).WaitOne(); isReleased = true; Trace("Wait(release): Result={0} Sync={1}", result == null ? "null" : result.ToString(), syncCompletion); #else this.AsyncWaitHandle.WaitOne(); #endif #if !MOBILE_DEVICE AsyncTracker.Yield(); #endif }
/// <summary> /// Release any resources associated with this object. /// </summary> public void Dispose() { using (TimedLock.Lock(this)) { #if DEBUG && !MOBILE_DEVICE if (!isCompleted) { AsyncTracker.Dump(this, "Disposing AsyncResult before operation completes."); SysLog.LogErrorStackDump("Disposing AsyncResult before operation completes."); return; } if (disposed) { var sb = new StringBuilder(1024); AsyncTracker.Dump(this, "AsyncResult has already been disposed."); sb.AppendLine("AsyncResult has already been disposed."); sb.AppendLine(); sb.AppendLine("Current stack:"); CallStack.AsyncTrace(1, true).Dump(sb); sb.AppendLine(); sb.AppendLine("Completion stack:"); completeStack.Dump(sb); SysLog.LogError(sb.ToString()); return; } this.disposed = true; this.completeStack = CallStack.AsyncTrace(1, true); #endif if (wait != null) { wait.Close(); wait = null; } } #if !MOBILE_DEVICE AsyncTracker.Yield(); #endif }
public override bool WaitOne() { using (TimedLock.Lock(owner)) { if (owner.WaitStack == null) { owner.WaitStack = CallStack.AsyncTrace(0, true); } if (isWaiting) { throw new InvalidOperationException("Another thread is already waiting."); } isWaiting = true; } return(wait.WaitOne()); }
public override bool WaitOne(int millisecondTimeout, bool exitContext) { using (TimedLock.Lock(owner)) { if (owner.WaitStack == null) { owner.WaitStack = CallStack.AsyncTrace(0, true); } if (!isWaiting) { throw new InvalidOperationException("Another thread is already waiting."); } isWaiting = true; } return(wait.WaitOne(millisecondTimeout, exitContext)); }
/// <summary> /// Notify the application that the operation is complete /// via the call back delegate. /// </summary> /// <param name="e"> /// The exception to be thrown in the <see cref="Finish" /> method /// or <c>null</c> if the operation was completed successfully. /// </param> /// <remarks> /// <note> /// Although this method may be called more than once for /// a particular async result instance, all but the first call /// will be ignored. /// </note> /// </remarks> public void Notify(Exception e) { #if DEBUG && !MOBILE_DEVICE // Wait up to a second to verify that Started() has been // called before reporting a warning. DateTime endTime = SysTime.Now + TimeSpan.FromSeconds(1); bool started = this.startStack != null; while (!started && SysTime.Now < endTime) { Thread.Sleep(10); started = this.startStack != null; } if (!started) { Trace("Notify({0}): Warning: Started() not called", exception != null ? exception.GetType().Name : (result == null ? "null" : result.ToString())); AsyncTracker.Dump(this, "Warning: Started() not called before Notifiy()"); } if (notifyQueued) { Trace("Notify({0}: Already queued)", exception != null ? exception.GetType().Name : (result == null ? "null" : result.ToString())); return; } Trace("Notify({0})", exception != null ? exception.GetType().Name : (result == null ? "null" : result.ToString())); notifyStack = CallStack.AsyncTrace(1, true); if (NotifyHook != null) { NotifyHook(this, e); } #endif #if !MOBILE_DEVICE AsyncTracker.Yield(); #endif using (TimedLock.Lock(this)) { notifyQueued = true; if (isCompleted) { return; // We've already signaled completion } exception = e; if (callback != null) { if (syncCompletion) { callback(this); } else { Helper.UnsafeQueueUserWorkItem(onComplete, this); } } else { isCompleted = true; if (wait != null) { wait.Set(); } } } #if !MOBILE_DEVICE AsyncTracker.Yield(); #endif }
public Sentinel(TimedLock tLock) { this.tLock = tLock; }
/// <summary> /// Constructor. /// </summary> /// <param name="tLock">The lock instance.</param> internal UndisposedLockException(TimedLock tLock) : base("A TimedLock instance was never properly disposed.") { this.tLock = tLock; }