请求是:使用SQL中的XEvents API,我必须提取并分析事件日志。我已对该会话“ QuickSessionTSQL”进行了个性化设置,使其仅记录过程或查询。下面的代码运行得很好,只是它一旦进入了第一个foreach块,就永远不会离开,它只是在等待事件来临,即使没有其他事件可以迭代。它创建了一个无限循环...
如果执行SQL查询,则它将生成一个事件,并且foreach将实时迭代该事件。
我试图打破它,但找不到合适的解决方案。
以前有没有人处理过?
//Connection string
SqlConnectionStringBuilder csb = new SqlConnectionStringBuilder();
csb.DataSource = @"DESKTOP-85BSKEM\MSSQLSERVER2016";
csb.InitialCatalog = @"master";
csb.IntegratedSecurity = true;
//Session name
string sessionName = "QuickSessionTSQL";
SqlConnection sqlConnection = new SqlConnection(csb.ConnectionString);
SqlStoreConnection connection = new SqlStoreConnection(sqlConnection);
BaseXEStore store = new XEStore(connection);
Session s = store.CreateSession(sessionName);
s.Start();
QueryableXEventData xEvents = new QueryableXEventData(csb.ConnectionString, sessionName, EventStreamSourceOptions.EventStream, EventStreamCacheOptions.DoNotCache);
foreach (var evt in xEvents)
{
foreach (PublishedEventField fld in evt.Fields)
{
string fieldName = fld.Name;
string fieldValue = fld.Value.ToString();
Debug.WriteLine(fieldName + " " + fieldValue);
}
}
为此选择IEnumerable具有一些缺点。它是所有集合的基本类型,并为您提供LINQ对流的访问。但是终止有点尴尬。
无论如何,我认为模式应该类似于枚举后台线程上的集合,并在希望枚举终止时从前台线程发出信号。像这样:
var xEvents = new QueryableXEventData(csb.ConnectionString, sessionName, EventStreamSourceOptions.EventStream, EventStreamCacheOptions.DoNotCache);
var cancellationTokenSource = new CancellationTokenSource();
var reader = Task.Factory.StartNew((o) =>
{
foreach (var evt in xEvents)
{
foreach (PublishedEventField fld in evt.Fields)
{
string fieldName = fld.Name;
string fieldValue = fld.Value.ToString();
Console.WriteLine(fieldName + " " + fieldValue);
}
}
}, TaskCreationOptions.LongRunning
, cancellationTokenSource.Token);
Console.WriteLine("Hit any key to exit");
Console.ReadKey();
cancellationTokenSource.Cancel();
xEvents.Dispose();
s.Stop();
reader.Wait();