我們有一個由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.");
}
}
}
請不要在不適合他們的環境中長時間運行進程,這只是最終會被撕掉的開始:http://stackoverflow.com/a/5553048/263681 –
謝謝格蘭特。我完全同意。 –
我以前見過使用.NET線程池的ASP.NET。以下是如何啓動請求並捕獲它可能拋出的任何異常:http://stackoverflow.com/a/753855/1429439 –