Open AlexisChung opened 4 years ago
Hi all, i found the problem, in RichTextBoxTarget.cs
textbox.BeginInvoke(new DelSendTheMessageToRichTextBox(SendTheMessageToRichTextBox), logMessage, rule, logEvent);
i changed BeginInvoke--->Invoke. and it work perfectly.
Isn't the whole thing much slower with Invoke?
Sounds like Control.Invoke becomes a throttle, where the writing waits for the GUI to keep up:
Maybe this change avoids filling up the window message-pump. But I think it should be optional. Think bulk insert would probably also help.
This is the first time I used the NLog.Windows.Forms in a project and I ran into the same problem with the RichTextBox thread hanging when I barraged the logger.
Can anyone direct me toward a guide to manually compile NLog.Windows.Forms and manually add it to a solution with multiple projects (I am using .NET 4.7.2)? I was going to check the suggestion by AlexisChung).
Using NLog 4.6.8 with NLog.Windows.Forms 4.3.0
Below is a test I made to blast the logger. I am assuming that the RichTextBox target is supposed to be wrapped by an async wrapper like the regular NLog.Targets targets. (Both wrapped and unwrapped hang the UI).
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
var config = NLog.LogManager.Configuration;
if(config == null) { config = new NLog.Config.LoggingConfiguration();}
var rtbTarget = new NLog.Windows.Forms.RichTextBoxTarget()
{
Name = "rtbTarget",
FormName = this.Name,
ControlName = rtbLogger.Name
};
var rtbTargetWrapper = new NLog.Targets.Wrappers.AsyncTargetWrapper()
{
Name = "rtbTargetWrapper",
WrappedTarget = rtbTarget
};
NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(rtbTargetWrapper, NLog.LogLevel.Trace);
logger.Trace("Logger started.");
KillTheWabbit(1000);
}
private void KillTheWabbit(int count)
{
for (int i = 0; i < count; i++)
{
logger.Trace("Kill the wabbit: {i}", i);
}
}
}
}
Isn't the whole thing much slower with Invoke?
Yes, but the form doesn't hang. I ran 3 cases with 10000 iterations:
Saturating log events to the RichTextBox is consuming all the bandwidth and leaving other 'Main Thread' UI tasks waiting to get it's share.
NLog version: (e.g. 4.6.8)
Platform: .Net 4.0
Current NLog config (xml or C#, if relevant)
code