2014-01-22 36 views
0

可能是锁定不能按我的预期工作。在这种情况下我应该使用静音吗?多线程使用列表

以下代码发生错误。在刺激它塞满了我的电子邮件服务器。

错误邮件内容:

的消息是:

指数阵列的边界之外。

堆栈跟踪是:

在System.Collections.Generic.List`1.Add(T项)
在TT.SharedServices.Auditor.Audit.AddAudit(AuditEventType pEvType,严重性pSeverity,的Int32 pClientId,字符串pSessionId,字符串pDetail,字符串pClientIp,字符串pEndUserIp)

的内部异常是:

请求参数是:会话ID:df58b273-c399-4692-8c14-7400b219769e详细信息:TimeTaken为LoadAgency:13毫秒

private void AddAudit(AuditEventType pEvType, Severity pSeverity, int pClientId, string pSessionId, string pDetail, 
        string pClientIp, string pEndUserIp) 
{ 
    // TO DO: also add Time 
    Trace.TraceInformation("Audit.Add entered : "); 
    try 
    { 
     if (pSeverity == Severity.High || Convert.ToBoolean(ConfigurationSystem.SharedApiConfig[pSeverity.ToString().ToLower()])) // chk option in config for adding audit 
     { 
      if (string.IsNullOrEmpty(pDetail)) 
      { 
       throw new ArgumentException("Detail should have a value", "pDetail"); 
      } 
      // adding data 
      var paramList = new DbParameter[8]; 
      paramList[0] = DataAccess.ParameterFactory.Create("@eventType", DbType.Int16, pEvType); 
      paramList[1] = DataAccess.ParameterFactory.Create("@severity", DbType.Int16, pSeverity); 
      paramList[2] = DataAccess.ParameterFactory.Create("@clientId", DbType.String, pClientId); 
      paramList[3] = DataAccess.ParameterFactory.Create("@detail", DbType.String, pDetail); 

      if (string.IsNullOrEmpty(pClientIp)) 
       paramList[4] = DataAccess.ParameterFactory.Create("@clientIP", DbType.String, DBNull.Value); 
      else 
       paramList[4] = DataAccess.ParameterFactory.Create("@clientIP", DbType.String, pClientIp); 

      if (string.IsNullOrEmpty(pEndUserIp)) 
       paramList[5] = DataAccess.ParameterFactory.Create("@endUserIP", DbType.String, DBNull.Value); 
      else 
       paramList[5] = DataAccess.ParameterFactory.Create("@endUserIP", DbType.String, pEndUserIp); 

      if (string.IsNullOrEmpty(pSessionId)) 
       paramList[6] = DataAccess.ParameterFactory.Create("@sessionId", DbType.String, 
                    new Guid().ToString()); 
      else 
       paramList[6] = DataAccess.ParameterFactory.Create("@sessionId", DbType.String, pSessionId); 

      paramList[7] = DataAccess.ParameterFactory.Create("@eventTime", DbType.DateTime, DateTime.Now); 
      if (IsBulkAuditSharedApi) 
      { 
       _auditQueueData.Add(paramList); 
       if (_auditQueueData.Count > MaxCountSharedApi) 
       { 
        AuditThreadData threadData = new AuditThreadData(); 
        lock (_auditQueueData) 
        { 
         threadData.Audit = new List<DbParameter[]>(); 
         threadData.Audit = _auditQueueData; 
         _auditQueueData = new List<DbParameter[]>(); 
        }       
        Thread callAuditPush = new Thread(AuditPushThread); 
        callAuditPush.Start(threadData); 
       } 
      } 
      else 
      { 
       int rowsAffected = DataAccess.ExecuteNonQuery(SpNames.IAPI_AddAudit, paramList); 
       Trace.TraceInformation("Audit.Add : Adding Audit data. rowsAffected = " + rowsAffected); 
      } 
      Trace.TraceInformation("Audit.Add exit : "); 
     } 
    } 
    catch (Exception exception) 
    {     
     string auditText = "The message is :" + exception.Message + "<br/> The Stack trace is :" + exception.StackTrace; 
     auditText += "<br/> The Inner Exception is:" + exception.InnerException; 
     auditText += "<br/> The Request parameters are : \n sessionID : " + pSessionId + "\n Details : " + pDetail; 
     Email.Email.SendingErrorEmail("Exception in Adding Audit in IAPI :", auditText, true, Email.Email.EmailSeverity.Error); 
    } 
} 


    struct AuditThreadData 
    { 
     internal List<DbParameter[]> Audit; 
    } 
    #region Private Static Methods 
    /// <summary> 
    /// This method will Audit the data(in Bulk) in DB 
    /// </summary> 
    /// <param name="objData"></param> 
    private void AuditPushThread(object objData) 
    { 
     try 
     { 
      var data = (AuditThreadData)objData; 
      if (data.Audit != null && data.Audit.Count > 0) 
      { 
       foreach (var paramList in data.Audit) 
       { 
        if (DataAccess != null) DataAccess.ExecuteNonQuery(SpNames.IAPI_AddAudit, paramList); 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      // catch block for precaution. 
      try 
      { 
       var log = new EventLog {Source = "Application"}; 
       log.WriteEntry("Bulk audit add failed:" + ex.Message + ex.InnerException, EventLogEntryType.Error, 2344);      
      } 
      catch 
      { 
       // to handle system security crash while writing log 
      } 
     } 
    } 
+0

你似乎没有对'_auditQueueData'做任何事情,它需要对它进行锁定,但是你不在'_auditQueueData.Add(paramList);'的锁定之外。很难理解没有看到更多的代码上下文 – CodingIntrigue

回答

0

你叫_auditQueueData.Add(paramList);外面的锁。试着把它放进去。

此外,您还锁定到List本身,而ICollections(如列表)有一个SyncRoot财产存在这个目的。该属性可能被框架的其他部分使用,如UI。您需要明确地将您的List转换为ICollection才能访问此属性。

+0

SyncRoot不是一个好主意。请参阅http://stackoverflow.com/a/728934/60761 –

+0

编写此代码的最佳方法是什么? – Rohit