//--- Methods --- /// <summary> /// Signal the RendezVousEvent. If a receiver continuation is present, trigger it. /// Otherwise, store the signal until a continuation is registered. /// </summary> /// <exception cref="InvalidOperationException">The RendezVousEvent instance has already been signaled.</exception> public void Signal() { if (HasCompleted) { throw new InvalidOperationException("event has already been used"); } object value = Interlocked.Exchange(ref _placeholder, TOKEN); if (value != null) { if (!(value is Action)) { throw new InvalidOperationException("event has already been signaled"); } Action handler = (Action)value; Interlocked.Decrement(ref _pendingCounter); if (_captured) { lock (Pending) { Pending.Remove(this); } } _placeholder = USED; try { handler(); } catch (Exception e) { // log exception, but ignore it; outer task is immune to it _log.WarnExceptionMethodCall(e, "Signal: unhandled exception in continuation"); } } }
/// <summary> /// Invoke a zero arg action. /// </summary> /// <param name="handler">Action to invoke.</param> public void Invoke(Action handler) { if (handler == null) { throw new ArgumentNullException("handler"); } if (_referenceCount < 1) { throw new InvalidOperationException("Cannot call invoke an unaquired TaskEnv"); } #pragma warning disable 219 System.Diagnostics.StackTrace stacktrace = DebugUtil.GetStackTrace(); #pragma warning restore 219 // check if handler can be invoked in-place or needs to queued up if (_dispatchQueue != null) { _dispatchQueue.QueueWorkItem(() => { // store current thread-specific settings TaskEnv previousEnv = _currentEnv; try { // set thread-specific settings _currentEnv = this; // execute handler handler(); } catch (Exception e) { _log.ErrorExceptionMethodCall(e, "Invoke: unhandled exception in handler"); } finally { Release(); // restore thread-specific settings _currentEnv = previousEnv; } }); } else { // store current thread-specific settings TaskEnv previousEnv = _currentEnv; try { // set thread-specific settings _currentEnv = this; // execute handler handler(); } catch (Exception e) { _log.WarnExceptionMethodCall(e, "Invoke: unhandled exception in handler"); } finally { Release(); // restore thread-specific settings _currentEnv = previousEnv; } } }
//--- Methods --- /// <summary> /// Adds a work-item to the thread pool. Depending on the implementation, this method may block the invoker /// or throw an exception if the thread pool cannot accept more items. /// </summary> /// <param name="callback">Item to add to the thread pool.</param> public void QueueWorkItem(Action callback) { try { callback(); } catch (Exception e) { // log exception, but ignore it; outer task is immune to it _log.WarnExceptionMethodCall(e, "QueueWorkItem: unhandled exception in callback"); } }
private void Dispose() { if (_iterator != null) { try { _iterator.Dispose(); } catch (Exception e) { _log.WarnExceptionMethodCall(e, "Dispose"); } finally { _iterator = null; } } }
//--- Methods --- public void InstanceStarted(DateTime eventTime) { try { XUri channel = _channel.At(SITE, STARTED); XUri resource = _apiUri.AsServerUri(); Queue(eventTime, channel, resource, new[] { _apiUri.AsServerUri().ToString() }, new XDoc("deki-event") .Elem("channel", channel) .Elem("uri", _apiUri.AsServerUri().ToString())); } catch (Exception e) { _log.WarnExceptionMethodCall(e, "InstanceStarted", "event couldn't be created"); } }