Я начал использовать ETW и незавершенный семантический блок регистрации из Entlib 6. Когда я использую async/await, CurrentThreadActivityId не задан в потоке продолжения, а структура TPL не регистрировать событие переноса. Это затрудняет выполнение сквозной трассировки.Трассировка EventSource с коррелированной активностью id
Согласно документации Microsoft, платформа TPL должна регистрировать событие переноса и генерировать новый activityid, но я не могу заставить его работать.
Вот небольшой пример, показывающий проблему:
для регистрации событий TPL, я использую следующее:
<eventSource name="System.Threading.Tasks.TplEventSource" level="Informational" matchAnyKeyword="1"/>
А вот мой тестовый код:
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsyncContextTest
{
class Program
{
static Guid _activityId = Guid.NewGuid();
static void Main(string[] args)
{
EventSource.SetCurrentThreadActivityId(_activityId);
Console.WriteLine(EventSource.CurrentThreadActivityId);
Task t = Task.Run(async() => await DoStuffAsync());
Console.WriteLine(EventSource.CurrentThreadActivityId);
Console.Read();
}
public static async Task DoStuffAsync()
{
var x = "one,two,three".Split(',');
Console.WriteLine(EventSource.CurrentThreadActivityId);
await Task.Delay(1000);
Console.WriteLine(EventSource.CurrentThreadActivityId);
var y = String.Join(",", x);
Console.WriteLine("Done");
}
}
}
Результаты
334540cc-ccb1-4196-8587-815abf237e4c
334540cc-ccb1-4196-8587-815abf237e4c
00000000-0000-0000-0000-000000000000
00000000-0000-0000-0000-000000000000
Done
У кого-нибудь есть простой пример, показывающий правильный способ выполнения сквозной трассировки с использованием ETW и асинхронного/ждущего?
EDIT:
Я был в состоянии получить эту работу должным образом с помощью прослушивателя в процессе, но не со слушателем вне-процесса. Из TPL ничего не записывается.
Это происходит потому, что консольное приложение использует 'ThreadPoolSynchronizationContext', который выполняет продолжения на произвольном Threadpool потоке. Будете ли вы использовать ETW оттуда или это просто для целей тестирования? –
@YuvalItzchakov - это будет служба Windows, так что да. Я реализовал контекст синхронизации STA, но слишком много накладных расходов. Дело в том, что ожидание должно регистрировать событие переноса и устанавливать новый идентификатор активности в новом потоке. Я узнал, что ожидание выполняет свою работу, но незавершенный семантический блок регистрации не собирает его, поэтому я представил это как ошибку для Microsoft. –
Я вижу, что вы говорите. Nice one :) –