Как стать автором
Обновить

Комментарии 16

Почему же не wcf, webapi или asp.net core наконец? :)
Предвидел такой вопрос. Изначально задумывалось написать за вечер и залить на пеки пользователей. Но все, переросло в нечто большее =) Wcf в перспективе.
У меня совет автору для второй части — для скриншота активного окна лучше использовать Alt+PrintScreen. Порой коммерческой тайной может быть даже панель задач со всеми значками.
Спасибо, учту )
Почему-бы просто не выполнять WMI запросы удалённо?
Если не секрет, чем не устроил BGinfo?
Зачем плодить конструкторы…

public User(string name, string pc, string ip, string version)
+ public User(string name, string pc, string ip, string version, byte[] screen)
= public User(string name, string pc, string ip, string version, byte[] screen=null)
Знакомое тело сервера. У Metanit'а такой пример был, кажется, для консольного чата.
Но речь о другом.

Почему, например, не сделать блок через using?

protected void Sender(TcpClient client, byte[] data)
        {
            try
            {
                Logger.add("Sender OK");
                using(BinaryWriter writer = new BinaryWriter(client.GetStream()))
                {
                    writer.Write(data);
                    writer.Flush();
                }
            }
            catch (Exception e)
            {
                Logger.add(e.Message);
            }
        }


И еще вопрос — не увидел блокировок в логгере. Как он себя поведет, когда несколько потоков его дернут одновременно?
Да, вы правы. Сходство есть. До это-го не разу не работал с сетью в c#, пришлось учиться на лету.
Можно через using. Так будет правильно и надежно.
Проблему с одновременным вызовом не решал. Еще есть моменты которые нужно исправить. Но и логгер без внимания не оставлю )
Ну и, кстати, о логгере. Сдается мне, что передавать стек в метод write через ссылку strs и в этом же методе очищать его непосредственно как log_massiv.Clear() — это не очень правильная практика.

Кроме того, не мешало бы завернуть File.AppendAllLines в блок try/catch на всякий случай.
В глаза бросается злоупотребление ключевым словом this — его имеет смысл применять тут в том случае, если в области видимости метода имя переменной совпадает с именем переменной в области видимости класса. Т.е.:

class MyClass
 {
    protected int num;

    public void NumMethod(int num)
    {
        this.num = num;
    }
}


Еще позволю себе совет: в именовании переменных и методов лучше сразу стараться себя приучить делать это dotnet way :) Никаких подчеркиваний в именах переменных/методов, за исключением приватных полей класса:

private ILogger _logger = null;
protected Stack<string> logMassiv = new Stack<string>();
protected int variableName = 0;

public void MyMetod(int variableOne, int variableTwo);

ну и т.д. :))
Но и логгер без внимания не оставлю

Делал реализацию своего логера через потокобезопасную очередь. Суть такова:
Логгер — синглтон, с единственным публичным методом а-ля «addLogRecord».
В обработчике метода происходит добавление записи в очередь и запуск отдельного потока, если он не запущен.
Сам процесс логирования осуществляется в отдельном потоке, который работает, если очередь не пустая.
Этот поток забирает записи из очереди, производит их вывод (например, в файл) и умирает, если записей больше нет.

Кстати, это очень плохой подход:
DateTime.Now.Day + "." + 
                DateTime.Now.Month + "." + 
                DateTime.Now.Year + " " + 
                DateTime.Now.Hour + ":" + 
                DateTime.Now.Minute + ":" + 
                DateTime.Now.Second;

Лучше так:
DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss");
Сам процесс логирования осуществляется в отдельном потоке, который работает, если очередь не пустая.
Этот поток забирает записи из очереди, производит их вывод (например, в файл) и умирает, если записей больше нет.


Для таких целей можно попробовать постоянно живущий BackgroundWorker и блокировку очереди сообщений посредством ReaderWriterLock. А чтобы не убивать каждый раз процесс, можно построить на базе AutoResetEvent флажок, который поднимается при записи сообщения в очередь и поднятия которого ждет фоновый процесс через WaitOne().
Конечно можно. Вариантов много. Суть не меняется — вынос процесса логирования в отдельный поток. С передачей в него динамической коллекции записей.
Кстати, если используется потокобезопасная очередь ConcurrentQueue, то никаких внешних блокировок не надо делать.
Возвращаясь к логам, я бы порекомендовал ввести систему ранжирования сообщений. DEBUG, INFO, ALERT, ERROR и т.д. Это позволит задавать, как разные стили вывода сообщений, так и фильтровать избыточные. Ну в общем насколько хватит фантазии.
интересное решение, жду продолжения
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации