我們有一個通過ThreadPool.QueueUserWorkItem命令啓動長時間運行任務的進程。取消正在使用ThreadPool.QueueUserWorkItem啓動的運行任務
裏面的每個任務,通過AppDomain.CreateDomain調用加載一個新的AppDomain,處理一堆東西並退出。有時,這些應用程序內部的處理時間過長,如果運行時間過長,則需要中止處理。
我想了解是否可以在不知情的情況下從外部中止這些線程,以便AppDomains正確卸載?
正如您在下面的代碼中看到的那樣,目前appdomain被創建爲局部變量,但如果需要它可以移動到類成員。我殺死線程的最好方法是在整個try/catch的「finally」子句中卸載該appdomain。但是,我不確定是否能夠從外部訪問它(appdomain),因爲AsyncExecute在不同於中止調用者的線程上運行。
這裏是啓動任務的處理功能:
public void AsyncExecute(RunningState runningState)
{
RunningState returnedState = null;
AppDomain runningApp = null;
try
{
{
var ads = new AppDomainSetup
{
ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
DisallowBindingRedirects = false,
DisallowCodeDownload = false,
ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
};
runningApp = AppDomain.CreateDomain("RemoteMonitor_" + runningState.LocalAccountInfo.Id, null,
ads);
var sub =
runningApp.CreateInstanceAndUnwrap("Processor", "Processor.ProcessorSub")
as ProcessorSub;
if (sub != null)
{
returnedState = sub.Run(runningState);
}
else
Logger.Instance.WriteCritical<ExecutableItem>("Cannot create Processor object");
}
}
catch (Exception ex)
{
Logger.Instance.WriteError<ExecutableItem>( ex.Message, ex);
}
finally
{
if (runningApp != null)
AppDomain.Unload(runningApp);
if (_onCompleteHandler == null)
Logger.Instance.WriteCritical<ExecutableItem>("Cannot complete task");
else
_onCompleteHandler.Invoke(returnedState);
}
}
在調用Run之後,您是否有辦法中止'sub'對象? – 2013-05-07 14:37:57
否定的。我可以調用這個:AppDomain.Unload(runningApp)來卸載整個appdomain對象。哪一個是我的首選 – Igorek 2013-05-07 14:45:18
這很容易造成數據丟失並可能使鎖打開...... – 2013-05-07 14:49:42