public void QueueChange(Mode mode, int seconds) { Log.Debug("Queuing mode: {0}, timeout: {1}", mode.Name, seconds); var activationTime = DateTime.Now + new TimeSpan(0, 0, seconds); lock (mChangeQueue) { mChangeQueue.Add(new ModeChange(mode, activationTime)); mChangeQueue.OrderBy(x => x.ActivationTime); mQueueEvent.Set(); } }
/// <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 }
private static AsyncEvent StreamCopy(Stream src, Stream dst, Func<bool> assertContinuation, Action onException = null, Action<int> onProgress = null) { var evt = new AsyncEvent(false, false); var exception = false; AsyncCallback cb = null; cb = (ar) => { var count = src.EndRead(ar); var readed = (byte[])ar.AsyncState; if (exception) return; if (count != 0) { lock (evt) { if (exception) return; var newArray = new byte[BLOCK_SIZE]; if (!assertContinuation()) return; if (onProgress != null) onProgress(count); src.BeginRead(newArray, 0, BLOCK_SIZE, cb, newArray); try { dst.Write(readed, 0, count); } catch (Exception e) { exception = true; if(onException != null) onException(); } } } else { lock (evt) { src.Close(); evt.Set(); } } }; var startBuffer = new byte[BLOCK_SIZE]; src.BeginRead(startBuffer, 0, BLOCK_SIZE, cb, startBuffer); return evt; }