Ejemplo n.º 1
0
 /// <summary>
 /// Writes an event to registered log instances
 /// </summary>
 /// <param name="type">
 /// The type of event
 /// </param>
 /// <param name="props">
 /// The event context properties
 /// </param>
 /// <param name="except">
 /// The event exception
 /// </param>
 /// <param name="format">
 /// The event message format string
 /// </param>
 /// <param name="objects">
 /// The event message format parameters
 /// </param>
 private void DispatchEvent(
     EventType type,
     Object props,
     Exception except,
     String format,
     Object[] objects)
 {
     // sample timestamps at method start, so that
      // they are as close to the event time as possible
      Int64 timestamp = GetTimestamp();
      DateTime time = DateTime.UtcNow;
      // ensure initialization/configuration is complete
      Initialize();
      if (instances.Count > 0)
      {
     Boolean hasAsync = false;
     // create the event context, and attach
     // all local event properties
     EventContext ctx = new EventContext()
     {
        Timestamp = timestamp,
        Time = time,
        Type = type,
        Source = this.sourceType,
        Exception = except,
        MessageFormat = format,
        MessageParams = objects
     };
     ctx.SetSourceProps(this.sourceType, this.sourceProps);
     ctx.SetEventProps(props);
     using (ConfigReadLock())
     {
        // sample global state on the current execution
        // context/thread, so that the remainder of event
        // processing can occur concurrently
        if (activeContexts.Any())
           ctx.SetGlobalProps(activeContexts.ToDictionary(
              m => m.Key,
              m => { try { return m.Value(); } catch { return null; } }
           ));
        // dispatch to any synchronous log instances
        foreach (Instance instance in instances)
           if (instance.Synchronous)
              DispatchEventInstance(instance, ctx);
           else
              hasAsync = true;
     }
     // dispatch to asynchronous log instances
     // . only start a new dispatcher work item if we sample a count
     //   of 0 in the event queue
     // . there is a potential race here in which multiple threads could
     //   sample a counter of 0, which would simply result in multiple
     //   dispatcher work items
     // . in addition, it is possible for a dispatcher to completely drain
     //   the queue and exit after the logging thread samples a nonzero count,
     //   although this would require the low-priority dispatcher to dispatch
     //   the last event faster than the logger could enqueue the next event,
     //   the only result being an event remaining in the queue longer
     // . these compromises are preferable to more heavy-handed synchronization
     //   mechanisms that would cause more contention on the logger and
     //   reduce application throughput
     if (hasAsync)
     {
        Boolean startDispatch = (eventQueue.Count == 0);
        eventQueue.Enqueue(ctx);
        if (startDispatch)
           ThreadPool.UnsafeQueueUserWorkItem(AsyncEventDispatcher, null);
     }
      }
 }