使用SQL XEvents QueryableXEventData的无限迭代

问题描述 投票:0回答:1

请求是:使用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);
            }
        }
c# sql sql-server visual-studio profiler
1个回答
0
投票

为此选择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();
© www.soinside.com 2019 - 2024. All rights reserved.