Отложенное форматирование сообщения трассировки через Func<string>?
В приложении, скомпилированном с включенной трассировкой, операторы трассировки всегда будут выполняться, даже если слушатель настроен на их удаление. Иногда для форматирования сообщения трассировки требуется нетривиальный объем работы, например:
Trace.Write(IAmExpensiveToRender.ToString() + " requested the following " + string.Join(",", itemList)));
Было бы неплохо отложить форматирование до тех пор, пока сообщения трассировки не будут отфильтрованы, и одним из способов реализации этого было бы передать метод трассировки a Func<string>
вместо string
:
Trace.Write((Func<string>)(() => IAmExpensiveToRender.ToString() + " requested the following " + string.Join(",", itemList)));
Это поддерживается System.Diagnostics.Trace
класс (так как он имеет универсальную перегрузку, которая принимает объекты), но требует, чтобы пользовательские слушатели вызывали фактическую строку, вызывая Func.
Я не могу представить, что никто еще не пробовал это. Существуют ли какие-либо библиотеки трассировки и / или слушатели, которые используют это? (Я не смог найти ни одного)
[Обновление] После некоторой рефлексии кажется, что перегрузки Trace, которые принимают строку форматирования + список параметров, уже поддерживают отложенное форматирование. Они передают строку + аргументы в TraceListener, который затем выполняет форматирование, только если сообщение действительно будет записано в файл.
1 ответ
Я не знаю о существующих средствах форматирования трассировки, которые поддерживают это.
Но так как мы знаем, что object
перегрузка для Trace.Write напечатает значение .ToString()
; мы можем воспользоваться этим:
class DeferredTraceExecutor
{
private readonly Func<string> traceMessage;
public DeferredTraceExecutor(Func<string> traceMessage)
{
this.traceMessage = traceMessage;
}
public override string ToString()
{
return traceMessage();
}
}
Затем используйте в своих сообщениях трассировки как:
Trace.Write(new DeferredTraceExecutor(() => IAmExpensiveToRender.Tostring());