Бесконечная итерация с SQL XEvents QueryableXEventData - PullRequest
0 голосов
/ 14 февраля 2020

Запрос: используя XEvents API из SQL, я должен извлечь и проанализировать журналы событий. Я персонализировал этот сеанс «QuickSessionT SQL», чтобы он только регистрировал процедуры или запросы. Приведенный ниже код работает просто отлично, за исключением того, что, как только он входит в первый блок foreach, он никогда не уходит, он просто ожидает наступления событий, даже если нет другого события для повторения. Он создает бесконечное l oop ...

Если я выполню запрос 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);
            }
        }

1 Ответ

0 голосов
/ 14 февраля 2020

Выбор 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...