Я хотел бы знать, каков ваш опыт использования EventSource для компонентов, которые являются общими и могут использоваться несколько раз в одном и том же процессе.
Один простой пример. Мой общий компонент — TestQueue, и я хотел бы использовать его несколько раз в моем процессе и снова в PerfView, чтобы увидеть, какое событие принадлежит какой очереди.
public class TestQueue<T>
{
private readonly IEtwQueue _etwQueue;
private readonly Queue<T> _instance = new Queue<T>();
public TestQueue(IEtwQueue etwQueue)
{
_etwQueue = etwQueue;
}
public void Enqueue(T item)
{
_instance.Enqueue(item);
_etwQueue.CommandEnqueued(_instance.Count);
}
public T Dequeue()
{
_etwQueue.CommandDequed(_instance.Count);
return _instance.Dequeue();
}
}
public interface IEtwQueue
{
void CommandEnqueued(int items);
void CommandDequed(int items);
}
[EventSource(Name = "Test-ETW-Queue")]
public class EtwQueue : EventSource, IEtwQueue
{
public static EtwQueue Log = new EtwQueue();
private EtwQueue() { }
[Event(1)]
public void CommandEnqueued(int items) { if (IsEnabled()) WriteEvent(1, items); }
[Event(2)]
public void CommandDequed(int items) { if (IsEnabled()) WriteEvent(2, items); }
}
И я хотел бы использовать его так:
TestQueue<string> testStringQueue = new TestQueue<string>(EtwQueue.Log);
TestQueue<int> testIntQueue = new TestQueue<int>(EtwQueue.Log);
testIntQueue.Enqueue(15);
testStringQueue.Enqueue("X");
Вот что у меня есть в PerfView:
Между этими двумя событиями нет никакой разницы. Я хотел бы знать, как я могу идентифицировать их, чтобы какое-то имя (строка) или идентификатор фигурировали как часть имени события? Я знаю, что мог бы использовать Задачи для логической группировки событий, но это не то, что я ожидал бы здесь, тем более, что они должны быть предопределены в источнике событий. Идентификатор действия также одинаков в случае использования.
Ваше здоровье!
Один из лучших способов реализации двух источников событий — это передача имени источника события через конструктор пользовательской реализации. Может быть, это способ сделать это :)
Таким образом, в пользовательском классе источника события нет атрибута EventSource, а конструктор имеет параметр имени источника события:
public class EtwQueueEventSource : EventSource, IEtwQueue
{
public EtwQueueEventSource(string sourceName) : base(sourceName) { }
[Event(1)]
public void CommandEnqueued(int items) { if (IsEnabled()) WriteEvent(1, items); }
[Event(2)]
public void CommandDequed(int items) { if (IsEnabled()) WriteEvent(2, items); }
}
Таким образом, предыдущий пример использования становится примерно таким:
TestQueue<string> testStringQueue = new TestQueue<string>(new EtwQueueEventSource("Test-ETW-Queue-String"));
TestQueue<int> testIntQueue = new TestQueue<int>(new EtwQueueEventSource("Test-ETW-Queue-Integer"));
testIntQueue.Enqueue(15);
testStringQueue.Enqueue("X");