如何处理触发事件中重叠的Console.Writeline()?

时间:2019-12-25 02:18:09

标签: c# events console-application overlapping console.writeline

嘿,我正在为自己的Windows Server编写RDP Bruteforce Protection程序,甚至在更改RDP端口后也会受到攻击:/

但是我已经受控制台登录的困扰,当几乎同时发生2次攻击时,控制台输出“重叠”,如:

enter image description here

显示我基本操作的简约代码:

watcher.EventRecordWritten +=
                new EventHandler<EventRecordWrittenEventArgs>(EventLogEventRead);

public static async void EventLogEventRead(object obj,
        EventRecordWrittenEventArgs arg)
    {            
        if (arg.EventRecord != null)
        {
            string IP = GetIPFromRecord(arg.EventRecord)

            var json = await new HttpClient().GetStringAsync("https://api.ipgeolocationapi.com/geolocate/" + IP);
            var jsonDeserialized = new JavaScriptSerializer().Deserialize<dynamic>(json);
            string country = jsonDeserialized["name"];


            Console.WriteLine("IP:\t" + IP);
            Console.WriteLine("Country:\t" + country);
        }
        else
        {
            Console.WriteLine("The event instance was null.");
        }
    }

完整代码(无错误消息类):Pastebin

那么解决这种问题的最优雅的方法是什么?

2 个答案:

答案 0 :(得分:3)

它重叠,因为您需要为单个日志条目多次调用Console.WriteLine()。您需要准备整个输出主体并将其立即写入控制台。

例如,更改

Console.WriteLine("IP:\t" + IP);
Console.WriteLine("Country:\t" + country);

var msg = $"IP:\t{IP}{Environment.NewLine}Country:\t{country}";
Console.WriteLine(msg);

或更妙的是,使用StringBuilder

var builder = new StringBuilder();
builder.AppendLine($"IP:\t{IP}");
builder.AppendLine($"Country:\t{country}");
Console.WriteLine(builder.ToString());

我还建议使用专用的日志记录框架,例如NLog(https://github.com/NLog/NLog)。如上所述,您仍然需要立即写入条目,但是如果需要,它可以帮助您对输出进行样式设置并在将来轻松添加其他目标(文件,网络等)。

答案 1 :(得分:1)

您应该使用锁:

watcher.EventRecordWritten +=
                new EventHandler<EventRecordWrittenEventArgs>(EventLogEventRead);


private static readonly object myLock = new object();

public static async void EventLogEventRead(object obj, EventRecordWrittenEventArgs arg)
{          

    if (arg.EventRecord != null)
    {
        string IP = GetIPFromRecord(arg.EventRecord)

        var json = await new HttpClient().GetStringAsync("https://api.ipgeolocationapi.com/geolocate/" + IP);
        var jsonDeserialized = new JavaScriptSerializer().Deserialize<dynamic>(json);
        string country = jsonDeserialized["name"];

        lock (myLock) {
            Console.WriteLine("IP:\t" + IP);
            Console.WriteLine("Country:\t" + country);
        }
    }
    else
    {   
        lock (myLock) {
            Console.WriteLine("The event instance was null.");
        }
    }

}