@@ -188,12 +188,21 @@ public RichTextBoxTarget()
188188 InternalLogger . Warn ( ex , "{0}: Failed to append RichTextBox" , this ) ;
189189 }
190190 } ) ;
191+ _sendTheMessagesToRichTextBox = new DelSendTheMessagesToRichTextBox ( ( txtbox , msgs ) =>
192+ {
193+ foreach ( var msg in msgs )
194+ {
195+ if ( msg . LogEvent != null )
196+ _sendTheMessageToRichTextBox . Invoke ( txtbox , msg . Message , msg . Rule , msg . LogEvent ) ;
197+ }
198+ } ) ;
191199 }
192200
193-
194201 private delegate void DelSendTheMessageToRichTextBox ( RichTextBox textBox , string logMessage , RichTextBoxRowColoringRule rule , LogEventInfo logEvent ) ;
202+ private delegate void DelSendTheMessagesToRichTextBox ( RichTextBox textBox , MessageInfo [ ] messages ) ;
195203
196204 private readonly DelSendTheMessageToRichTextBox _sendTheMessageToRichTextBox ;
205+ private readonly DelSendTheMessagesToRichTextBox _sendTheMessagesToRichTextBox ;
197206
198207 private delegate void FormCloseDelegate ( ) ;
199208
@@ -740,6 +749,65 @@ protected override void CloseTarget()
740749 DetachFromControl ( ) ;
741750 }
742751
752+ /// <inheritdoc />
753+ protected override void Write ( IList < AsyncLogEventInfo > logEvents )
754+ {
755+ var textbox = TargetRichTextBox ;
756+ if ( logEvents . Count < 10 || textbox is null || textbox . IsDisposed || ! textbox . InvokeRequired )
757+ {
758+ base . Write ( logEvents ) ;
759+ }
760+ else
761+ {
762+ // Single array-allocation instead of flooding the message-pump with BeginInvoke-calls
763+ var logMessages = new MessageInfo [ logEvents . Count ] ;
764+ for ( int i = 0 ; i < logEvents . Count ; i ++ )
765+ {
766+ var logEvent = logEvents [ i ] ;
767+ try
768+ {
769+ string logMessage = RenderLogEvent ( Layout , logEvent . LogEvent ) ;
770+ RichTextBoxRowColoringRule matchingRule = FindMatchingRule ( logEvent . LogEvent ) ;
771+ logMessages [ i ] = new MessageInfo ( logMessage , matchingRule , logEvent . LogEvent ) ;
772+ }
773+ catch ( Exception ex )
774+ {
775+ InternalLogger . Warn ( ex , "{0}: Failed to render log event" , this ) ;
776+ if ( LogManager . ThrowExceptions )
777+ throw ;
778+ logEvent . Continuation ( ex ) ;
779+ }
780+ }
781+
782+ bool messageSent = false ;
783+
784+ try
785+ {
786+ // Single BeginInvoke with single method-parameters-allocation
787+ textbox . BeginInvoke ( _sendTheMessagesToRichTextBox , textbox , logMessages ) ;
788+ messageSent = true ;
789+ for ( int i = 0 ; i < logEvents . Count ; i ++ )
790+ logEvents [ i ] . Continuation ( null ) ;
791+ }
792+ catch ( Exception ex )
793+ {
794+ InternalLogger . Warn ( ex , "{0}: Failed to append RichTextBox" , this ) ;
795+ if ( LogManager . ThrowExceptions )
796+ throw ;
797+ for ( int i = 0 ; i < logEvents . Count ; i ++ )
798+ logEvents [ i ] . Continuation ( ex ) ;
799+ }
800+ finally
801+ {
802+ foreach ( var logMessage in logMessages )
803+ {
804+ if ( logMessage . LogEvent != null )
805+ HandleMessageRetension ( textbox , logMessage . LogEvent , logMessage . Message , logMessage . Rule , messageSent ) ;
806+ }
807+ }
808+ }
809+ }
810+
743811 /// <summary>
744812 /// Log message to RichTextBox.
745813 /// </summary>
@@ -766,9 +834,13 @@ protected override void Write(LogEventInfo logEvent)
766834
767835 string logMessage = RenderLogEvent ( Layout , logEvent ) ;
768836 RichTextBoxRowColoringRule matchingRule = FindMatchingRule ( logEvent ) ;
769-
770837 bool messageSent = DoSendMessageToTextbox ( logMessage , matchingRule , logEvent ) ;
771838
839+ HandleMessageRetension ( textbox , logEvent , logMessage , matchingRule , messageSent ) ;
840+ }
841+
842+ private void HandleMessageRetension ( RichTextBox ? textbox , LogEventInfo logEvent , string logMessage , RichTextBoxRowColoringRule matchingRule , bool messageSent )
843+ {
772844 if ( messageSent )
773845 {
774846 //remember last logged text box
@@ -892,8 +964,8 @@ private void SendTheMessageToRichTextBox(RichTextBox textBox, string logMessage,
892964 {
893965 var wordRulePattern = wordRule . Regex ? . Render ( logEvent ) ?? string . Empty ;
894966 var wordRuleText = wordRule . Text ? . Render ( logEvent ) ?? string . Empty ;
895- var wordRuleWholeWords = wordRule . WholeWords . RenderValue ( logEvent ) ;
896- var wordRuleIgnoreCase = wordRule . IgnoreCase . RenderValue ( logEvent ) ;
967+ var wordRuleWholeWords = wordRule . WholeWords ? . RenderValue ( logEvent ) ?? false ;
968+ var wordRuleIgnoreCase = wordRule . IgnoreCase ? . RenderValue ( logEvent ) ?? false ;
897969
898970 var matches = wordRule . ResolveRegEx ( wordRulePattern , wordRuleText , wordRuleWholeWords , wordRuleIgnoreCase ) . Matches ( textBox . Text , startIndex ) ;
899971 foreach ( Match ? match in matches )
0 commit comments