2014-01-22 2 views
0

예상대로 잠금이 작동하지 않을 수 있습니다. 이 경우 뮤트를 사용해야합니까?목록을 사용하여 멀티 스레드 됨

다음 코드에서 오류가 발생했습니다. 그것은 내 이메일 서버를 찌르다.

오류 메일 내용 :

메시지는 다음과 같습니다

인덱스 배열의 범위를 벗어난 것입니다.

스택 추적 : System.Collections.Generic.List`1.Add (T 항목) TT.SharedServices.Auditor.Audit.AddAudit에서
(AuditEventType pEvType, 심각도에

pSeverity, INT32 pClientId, 문자열 pSessionId, 문자열 pDetail, 문자열 pClientIp, 문자열 pEndUserIp)

내부 예외는 다음과 같습니다

,

요청 매개 변수는 다음과 같습니다 sessionID와 : df58b273-c399-4692-8c14-7400b219769e 세부 사항 : TimeTaken LoadAgency을 위해 : 13 MS

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); 외부를 호출합니다. 그것을 안으로 넣어보십시오.

또한 ICollections (예 : 목록)은 SyncRoot 속성을 가지고 있지만 List 자체는 잠그고 있습니다. 이 속성은 UI와 같은 프레임 워크의 다른 부분에서 사용할 수 있습니다. 이 속성에 액세스하려면 ListICollection으로 명시 적으로 전송해야합니다.

+0

SyncRoot는 그렇게 좋은 생각이 아닙니다. http://stackoverflow.com/a/728934/60761 –

+0

이 코드를 작성하는 가장 좋은 방법은 무엇입니까?를 참조하십시오. – Rohit