问题
I have got below exception in a log file.
System.ArgumentOutOfRangeException
: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name:chunkLength
atSystem.Text.StringBuilder.ToString()
I believe this is because of string Builder which is not a thread safe. But I am stumbled on how to make my string builder to thread safe in below recursive function.
public static class StringExtensions
{
/// <summary>
/// The log key builder
/// </summary>
private static StringBuilder logKeyBuilder;
public static string ConcatLogKeyWithExceptionMessage<T>(this T entity, string configuredLogKeys, bool logOnlySingleKey, string exceptionMessage, bool firstInvocation = true) where T : class
{
logKeyBuilder = logKeyBuilder ?? new StringBuilder();
if (entity != null)
{
var objType = entity.GetType();
var properties = objType.GetProperties();
foreach (var property in properties)
{
var propValue = property.GetValue(entity, null);
var elems = propValue as IList;
if (elems != null)
{
foreach (var item in elems)
{
{
ConcatLogKeyWithExceptionMessage(item, configuredLogKeys, logOnlySingleKey, exceptionMessage, false);
}
}
}
else
{
// This will not cut-off System.Collections because of the first check
if (property.PropertyType.Assembly == objType.Assembly)
{
ConcatLogKeyWithExceptionMessage(propValue, configuredLogKeys, logOnlySingleKey, exceptionMessage, false);
}
else
{
configuredKeysArray = configuredKeysArray ?? (!string.IsNullOrEmpty(configuredLogKeys) ? configuredLogKeys.Split(',') : new string[0]);
foreach (var configLogKey in configuredKeysArray)
{
if (string.Compare(configLogKey.Trim(), property.Name.Trim(), StringComparison.OrdinalIgnoreCase) == 0)
{
configuredKeysArray = configuredKeysArray.Where(x => x != configLogKey).ToArray();
logKeyBuilder.Append(property.Name);
logKeyBuilder.Append(" ");
logKeyBuilder.Append("-");
logKeyBuilder.Append(" ");
logKeyBuilder.Append(property.GetValue(entity));
logKeyBuilder.Append(" ");
if (logOnlySingleKey)
{
break;
}
}
}
}
}
}
}
logKeyBuilder = firstInvocation ? logKeyBuilder.Append(exceptionMessage) : logKeyBuilder;
return logKeyBuilder.ToString();
}
}
回答1:
Using lock:
private static object lockObject = new object();
public static string ConcatLogKeyWithExceptionMessage<T>(this T entity, string configuredLogKeys, bool logOnlySingleKey, string exceptionMessage, bool firstInvocation = true) where T : class
{
lock(lockObject )
{
// rest of your code here
}
}
Or move your static field to be a local variable inside the method.
来源:https://stackoverflow.com/questions/38564486/system-argumentoutofrangeexception-parameter-name-chunklength-at-system-text-st