我们有一个进程通过 ThreadPool.QueueUserWorkItem 命令启动长时间运行的任务。
里面的每个任务,通过 AppDomain.CreateDomain 调用加载一个新的 AppDomain,处理一堆东西并退出。有时,这些应用程序内部的处理时间过长,如果运行时间过长,就需要中止它们。
我想了解是否可以在他们不知情的情况下从外部中止这些线程,以便正确卸载它们的 AppDomains?
正如您在下面的代码中看到的,目前 appdomain 是作为局部变量创建的,但如果需要,它可以向上移动到类成员。我杀死线程的最佳方法是卸载该 appdomain,就像在整个 try/catch 的“finally”子句中所做的那样。但是,我不确定我是否能够“从外部”访问它(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);
}
}