NLog: PropertiesDictionary - Collection was modified exception
NLog version: 4.7.10
Platform: netstandard2.0
I have implemented custom NLog target inherited from NLog.Targets.TargetWithContext
. The target calls GetAllProperties(LogEventInfo)
method within Write(LogEventInfo)
:
protected override async void Write(LogEventInfo logEvent)
{
// do something
try
{
// do something
IEnumerable<KeyValuePair<string, object>> properties = GetAllProperties(logEvent).ToList();
foreach (KeyValuePair<string, object> property in properties)
{
// iterate properties
}
// await something
}
catch (Exception error)
{
InternalLogger.Error(error, "{0}[{1}]. Failed to send {2}.", GetType(), Name, logEvent);
}
}
The target is used by an application with following configuration:
{
"NLog": {
"autoReload": true,
"throwConfigExceptions": true,
"internalLogLevel": "Debug",
"internalLogFile": "${basedir}/Logs/nlog.log",
"extensions": [{
"assembly": "NLog.Extensions.Logging"
}, {
"assembly": "GrayNLog"
}
],
"default-wrapper": {
"type": "AsyncWrapper",
"overflowAction": "Block"
},
"targets": {
"graylog": {
"type": "UdpGelf",
"host": "myhost.loc",
"port": 12201,
"layout": null,
"contextProperties": [{
"name": "service",
"layout": "${appdomain:format={1\\}}"
}, {
"name": "serviceVersion",
"layout": "${assembly-version:type=Informational}"
}, {
"name": "log",
"layout": "${logger}"
}, {
"name": "error",
"layout": "${exception:format=toString}"
}
]
}
},
"rules": [{
"logger": "*",
"writeTo": "graylog",
"minLevel": "Trace"
}
]
}
}
The application uses following to apply the configuration:
hostBuilder.ConfigureLogging((context, logging) =>
{
var configuration = context.Configuration.GetSection("NLog");
NLog.LogManager.Configuration = new NLogLoggingConfiguration(configuration);
logging
.ClearProviders()
.SetMinimumLevel(LogLevel.Trace)
.AddNLog();
});
I was surprised to get following exception:
Exception: System.InvalidOperationException: Collection was modified; enumeration operation may not execute
at System.Collections.Generic.Dictionary`2.Enumerator.MoveNext()
at NLog.Internal.PropertiesDictionary.DictionaryEnumeratorBase.MoveNextValidEventProperty()
at NLog.Targets.TargetWithContext.GetAllProperties(LogEventInfo logEvent, IDictionary`2 combinedProperties)
As you can see, I have tried to copy the dictionaty to list to avoid the exception. But it doesn’t help. Why is the dictionary modified after GetAllProperties
returns it?
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 18 (12 by maintainers)
That’s great! The 4.7.12 version has treated my pain.