我们有一个通过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