Вопрос об эффективной регистрации в C # - PullRequest
4 голосов
/ 14 апреля 2010

Я написал простой класс для отладки, и я вызываю метод Debugger.WriteLine (...) в своем коде так:

Debugger.WriteLine("[Draw]", "InProgress",
    "[x,y] = " + x.ToString("0.00") + 
    ", " + y.ToString("0.00") + 
    "; pos = " + lastPosX.ToString() + "x" + 
    lastPosY.ToString() + " -> " + posX.ToString() + 
    "x" + posY.ToString() + "; SS = " + 
    squareSize.ToString() + "; MST = " + 
    startTime.ToString("0.000") + "; Time = " + time.ToString() +
    phase.ToString(".0000") + "; progress = " + 
    progress.ToString("0.000") + "; step = " + 
    step.ToString() + "; TimeMovementEnd = " + 
    UI.MovementEndTime.ToString()
);

Тело процедуры Debugger.WriteLine компилируется только в режиме отладки (директивы #if, #endif). Что меня беспокоит, так это то, что мне часто требуется вызов ToString () в вызове Debugger.WriteLine, который является дорогостоящим, потому что он создает все еще новые строки (например, для изменения номера). Как решить эту проблему?

Несколько замечаний / вопросов по отладке / трассировке:

  • Я не хочу оборачивать каждый Debugger.WriteLine в оператор IF или использовать директивы препроцессора, чтобы исключить методы отладки, потому что это неизбежно приведет к не очень читабельному коду и требует слишком большого набора текста. .

  • Я не хочу использовать какие-либо рамки для трассировки / отладки. Я хочу попробовать запрограммировать это сам.

  • Не исключены ли методы трассировки при компиляции в режиме выпуска? Если это так, то возможно ли, что мои методы будут вести себя аналогично?

  • С помощью статического метода String.Format Я могу сделать это:

    output = String.Format ("Вам сейчас {0} лет.", Лет);

Что, похоже, приятно. Это решение моей проблемы с ToString ()?

Ответы [ 6 ]

4 голосов
/ 14 апреля 2010

Используя Reflector, я обнаружил, что Debug.Writeline объявлен так:

[Conditional("DEBUG")]
public static void WriteLine(string message)

Это означает, что в режиме Release все вызовы этого метода исключаются из кода.

Например, этот код:

public static void Test(int a)
{
    string b = Console.ReadLine();
    Debug.WriteLine(a + " " + b);
    Console.WriteLine(a + " " + b);
}

компилируется в режиме выпуска до:

public static void Test(int a)
{
    Console.WriteLine(a + " " + Console.ReadLine());
}
3 голосов
/ 14 апреля 2010

Используйте StringBuilder для создания выходных строк вместо объединения каждого значения.

И вы можете создать свой собственный класс отладчика (MyDbg), который содержит член WriteLine, содержимое которого вы можете окружить директивами компиляции. Он не будет полностью компилировать код отладки, но превратит ваши вызовы MyDbg.WriteLine в no-ops.

Вот краткий набросок класса:

using System;
using System.Text ;

public static class MyDbg
{
    public static void WriteLine(string str) // and some other params
    {
        #if DEBUG

        StringBuilder sb = new StringBuilder();
        sb.Append(str);
        // etc. appending other params as you see fit
        #endif
    }
}

OR

[Conditional("DEBUG")]
public static class MyDbg
{
    public static void WriteLine(string str) // and some other params
    {
        StringBuilder sb = new StringBuilder();
        sb.Append(str);
        // etc. appending other params as you see fit
    }
}

Вы, конечно, изменили бы его под свои нужды. И вместо того, чтобы создавать отдельный класс, вы можете создать метод-член, если #if DEBUG / # endif встроен для отображения своего собственного состояния в отладчике.

2 голосов
/ 14 апреля 2010

Для ведения журнала взгляните на такие инфраструктуры, как Log4net или библиотека Enterprise. Они делают регистрацию настраиваемой во многих отношениях. Даже если вы хотите войти в систему вообще.

НТН

1 голос
/ 14 апреля 2010

Шаблон, который я использую, предназначен для определения интерфейса ведения журнала (ILogger), который вводит зависимость во все классы

public class MyClassThatLogs
{
    public MyClassThatLogs(ILogger logger)
    {
        try
        {
            logger.Write("bla bla bla");
        }
        catch(Exception ex)
        {
            logger.Write(ex); //overload of Write() that takes in an Exception
        }
    }
}

Таким образом, когда вы обновляете его, вы можете передать «настоящий» регистратор или фальшивый / фальшивый

var mc = new MyClassThatLogs(new FakeLogger());

Теперь вы абстрагировались от необходимости знать в классе MyClassThatLogs, что происходит с ведением журнала. Основные твердые вещи. Таким образом, у 'top' (скажем, метода main () консоли) будет директива IF DEBUG, а затем передается правильная реализация регистратора.

1 голос
/ 14 апреля 2010

Используя string.Format(), ожидаемый результат будет фактически легче распознать, просто взглянув на код (IMHO):

Debug.WriteLine(string.Format(
    "[Draw]InProgress[x,y] = {0:0.00}, {1:0.00}; pos = {2}x{3} -> {4}x{5}; ...",
    x, y,
    lastPosX, lastPosY,
    posX, posY,
    ...));
0 голосов
/ 14 апреля 2010
  1. Вам не нужно переносить каждую строку. Просто напишите вспомогательный метод, содержащий Debug.WriteLine, и включите / выключите его с помощью флага (обычно bool).

  2. Трассировка будет в вашем коде даже в режиме релиза. Вы можете настроить его, см http://msdn.microsoft.com/en-us/library/system.diagnostics.tracelistener.aspx

  3. string.Format вызывает ToString () для аргументов внутри, поэтому никакой пользы нет.

...