{
List<SessionInfo> liveSessionList = null;
- GetSessionInfo((Action<int, long>)
- ((etwSessionId, matchAllKeywords) =>
- GetSessionInfoCallback(etwSessionId, matchAllKeywords, ref liveSessionList)));
+ GetSessionInfo(
+ (int etwSessionId, long matchAllKeywords, ref List<SessionInfo> sessionList) =>
+ GetSessionInfoCallback(etwSessionId, matchAllKeywords, ref sessionList),
+ ref liveSessionList);
List<Tuple<SessionInfo, bool>> changedSessionList = new List<Tuple<SessionInfo, bool>>();
}
}
+ private delegate void SessionInfoCallback(int etwSessionId, long matchAllKeywords, ref List<SessionInfo> sessionList);
+
/// <summary>
/// This method enumerates over all active ETW sessions that have enabled 'this.m_Guid'
/// for the current process ID, calling 'action' for each session, and passing it the
/// ETW session and the 'AllKeywords' the session enabled for the current provider.
/// </summary>
- private unsafe void GetSessionInfo(Action<int, long> action)
+ private unsafe void GetSessionInfo(SessionInfoCallback action, ref List<SessionInfo> sessionList)
{
// We wish the EventSource package to be legal for Windows Store applications.
// Currently EnumerateTraceGuidsEx is not an allowed API, so we avoid its use here
var enabledInfos = (UnsafeNativeMethods.ManifestEtw.TRACE_ENABLE_INFO*)&providerInstance[1];
// iterate over the list of active ETW sessions "listening" to the current provider
for (int j = 0; j < providerInstance->EnableCount; j++)
- action(enabledInfos[j].LoggerId, enabledInfos[j].MatchAllKeyword);
+ action(enabledInfos[j].LoggerId, enabledInfos[j].MatchAllKeyword, ref sessionList);
}
if (providerInstance->NextOffset == 0)
break;
string keywordBitString = dataAsString.Substring(startIdx, endIdx-startIdx);
int keywordBit;
if (0 < endIdx && int.TryParse(keywordBitString, out keywordBit))
- action(etwSessionId, 1L << keywordBit);
+ action(etwSessionId, 1L << keywordBit, ref sessionList);
}
}
}
public EventListener()
{
// This will cause the OnEventSourceCreated callback to fire.
- CallBackForExistingEventSources(true, (obj, args) => args.EventSource.AddListener(this));
+ CallBackForExistingEventSources(true, (obj, args) => args.EventSource.AddListener((EventListener)obj));
}
/// <summary>
stringBuilder.Append(eventMessage, startIndex, count);
}
+ private static readonly string[] s_escapes = { "&", "<", ">", "'", """, "%r", "%n", "%t" };
// Manifest messages use %N conventions for their message substitutions. Translate from
// .NET conventions. We can't use RegEx for this (we are in mscorlib), so we do it 'by hand'
private string TranslateToManifestConvention(string eventMessage, string evtName)
}
else if ((chIdx = "&<>'\"\r\n\t".IndexOf(eventMessage[i])) >= 0)
{
- string[] escapes = { "&", "<", ">", "'", """, "%r", "%n", "%t" };
- var update = new Action<char, string>(
- (ch, escape) =>
- {
- UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar);
- i++;
- stringBuilder.Append(escape);
- writtenSoFar = i;
- });
- update(eventMessage[i], escapes[chIdx]);
+ UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar);
+ i++;
+ stringBuilder.Append(s_escapes[chIdx]);
+ writtenSoFar = i;
}
else
i++;