ThreadPool是.net System.Threading命名空間下的線程池對象。使用QueueUserWorkItem實現對異步委托的先進先出有序的回調。如果在回調的方法里面發生異常則應用程序會出現閃退。當然是指不處理那個異常的情況下。這不公司的CMS在生產環境頻頻出現閃退的情況。該死的是,原來用老機器配置不高的情況下沒有出現過。換了更好的新機器后出現的。
//
// 摘要:
// 將方法排入隊列以便執行,並指定包含該方法所用數據的對象。此方法在有線程池線程變得可用時執行。
//
// 參數:
// callBack:
// System.Threading.WaitCallback,它表示要執行的方法。
//
// state:
// 包含方法所用數據的對象。
//
// 返回結果:
// 如果此方法成功排隊,則為 true;如果未能將該工作項排隊,則引發 System.NotSupportedException。
//
// 異常:
// T:System.NotSupportedException:
// 承載公共語言運行時 (CLR) 的宿主不支持此操作。
//
// T:System.ArgumentNullException:
// callBack 為 null。
[SecuritySafeCritical]
public static bool QueueUserWorkItem(WaitCallback callBack, object state);
經過一番測試重新了故障現象,但由於是生產環境代碼不好大動,看來解決方案就是吞掉異常,讓程序不再閃退一種解決辦法了。
編碼測試過程
using System;
using System.Threading;
namespace ConsoleShell3
{
//164-184
class Program
{
static object queueObj = new object();
static CoreThreadPool pool = new CoreThreadPool();
static void Main(string[] args)
{
Console.WriteLine("Main Thread OK...");
pool.Exceute += Pool_Exceute;
pool.Start();
pool.Post(queueObj);
Thread thread = new Thread(() =>
{
while (true)
{
Thread.Sleep(1000);
queueObj = (object)DateTime.Now.Ticks;
Console.WriteLine(DateTime.Now);
pool.Post(queueObj);
}
});
thread.Start();
Console.ReadLine();
}
private static void Pool_Exceute(object obj)
{
ThreadPool.QueueUserWorkItem(CallbackDemoViod, obj);
}
/// <summary>
/// 我的方案就是在這里把這個回調的方法用try catch包裹起來,吞到出現的異常
/// </summary>
/// <param name="obj"></param>
private static void CallbackDemoViod(object obj)
{
try
{
var inObj = obj;
var ex = new Exception("!!!!");
throw ex;
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
//以下不catch異常就會導致閃退
//var inObj = obj;
//var ex = new Exception("!!!!");
//throw ex;
}
}
}
處理前后對比
處理前

處理后

