2012-11-05 63 views
2

我們有一個由Web請求啓動的長時間運行的進程。爲了讓流程時間完成,我們將它放在一個新線程中,並使用Mutex來確保只有一個流程實例可以運行。此代碼按照我們的開發和分段環境中的預期運行,但在我們的生產環境中使用空引用異常失敗。我們的應用程序日誌記錄沒有捕獲任何東西,我們的操作人員正在報告它正在崩潰AppPool。 (這似乎是一個環境問題,但我們必須繼續假設環境配置相同。)到目前爲止,我們還無法確定空引用的位置。異常日誌記錄掩碼中的空引用異常真錯誤

下面是從應用程序事件日誌例外:

Exception: System.NullReferenceException 
Message: Object reference not set to an instance of an object. 
StackTrace: at Jobs.LongRunningJob.DoWork() 
    at System.Threading.ExecutionContext.runTryCode(Object userData) 
    at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart() 

這裏是代碼(略消毒):

public class LongRunningJob: Job 
{ 
    private static Mutex mutex = new Mutex(); 

    protected override void PerformRunJob() 
    { 
     var ts = new ThreadStart(LongRunningJob.DoWork); 
     var thd = new Thread(ts); 
     thd.IsBackground = true; 
     thd.Start(); 
    } 

    private static void DoWork() 
    { 
     var commandTimeOut = 180; 

     var from = DateTime.Now.AddHours(-24); 
     var to = DateTime.Now; 

     if (mutex.WaitOne(TimeSpan.Zero)) 
     { 
      try 
      { 
       DoSomethingExternal(); // from what we can tell, this is never called 
      } 
      catch (SqlException sqlEx) 
      { 
       if (sqlEx.InnerException.Message.Contains("timeout period elapsed")) 
       { 
        Logging.LogException(String.Format("Command timeout in LongRunningJob: CommandTimeout: {0}", commandTimeOut), sqlEx); 
       } 
       else 
       { 
        Logging.LogException(String.Format("SQL exception in LongRunningJob: {0}", sqlEx.InnerException.Message), sqlEx); 
       } 
      } 
      catch (Exception ex) 
      { 
       Logging.LogException(String.Format("Error processing data in LongRunningJob: {0}", ex.InnerException.Message), ex); 
      } 
      finally 
      { 
       mutex.ReleaseMutex(); 
      } 
     } 
     else 
     { 
      Logging.LogMessage("LongRunningJob is already running."); 
     } 
    } 
} 
+4

請不要在不適合他們的環境中長時間運行進程,這只是最終會被撕掉的開始:http://stackoverflow.com/a/5553048/263681 –

+0

謝謝格蘭特。我完全同意。 –

+0

我以前見過使用.NET線程池的ASP.NET。以下是如何啓動請求並捕獲它可能拋出的任何異常:http://stackoverflow.com/a/753855/1429439 –

回答

3

爲了找到一個NullReferenceException基本上你檢查每一個提領操作。我只能在下列可疑一個看到:

ex.InnerException.Message 

你不能假設ex.InnerException不爲空。

+1

usr - 我相信你可能會找到一些東西。可能我們的異常日誌記錄正在拋出它自己的異常,它掩蓋了原始問題。我們將探索這個選項。 –