Отложенное форматирование сообщения трассировки через 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());
Другие вопросы по тегам