2016-07-25 188 views
-1

我在日志文件中得到了以下异常。System.ArgumentOutOfRangeException参数名称:在System.Text.StringBuilder.ToString()的chunkLength()

“System.ArgumentOutOfRangeException:索引超出范围必须是不低于集合的大小负少 参数名:。chunkLength 在System.Text.StringBuilder.ToString()”

我相信这是因为字符串生成器不是线程安全的。但我偶然发现如何使我的字符串生成器线程安全在下面的递归函数。

任何想法将不胜感激。谢谢。

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(); 
    } 
} 

回答

0

使用锁:

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 
    } 
} 

或移动您的静态字段是方法内的局部变量。

+0

但这可能会影响多线程环境的性能?我正在寻找一个没有锁的解决方案 –

+0

@ChandraMohan为什么你有你的构建静态字段? – user3185569

+0

没有使stringbuilder为静态的具体原因。正如resharper建议我将其视为静态。如果我把这个文件作为局部变量传递给我的静态方法就是解决了这个问题。但我的静态方法是递归方法。 –