C# 卸载appdomain时出错。(HRESULT的异常:0x801315),Windows服务内部
我在windows服务中收到此错误。 这与我之前在问题中讨论的服务相同 代码修改为使用C# 卸载appdomain时出错。(HRESULT的异常:0x801315),Windows服务内部,c#,exception,appdomain,C#,Exception,Appdomain,我在windows服务中收到此错误。 这与我之前在问题中讨论的服务相同 代码修改为使用Parallel.ForEach(我自己的版本,因为这是一个3.5 windows服务)。并行使用的原因是卸载每个域花费的时间太长,并行运行它们应该会更快(看起来是即使只有一个线程在执行每次卸载?!) 根据其他帖子,我只能猜测这在某种程度上是因为我正在使用线程池线程来卸载AppDomains。我就是不知道如何避免它 public partial class SomeService : ServiceBase {
Parallel.ForEach
(我自己的版本,因为这是一个3.5 windows服务)。并行使用的原因是卸载每个域花费的时间太长,并行运行它们应该会更快(看起来是即使只有一个线程在执行每次卸载?!)
根据其他帖子,我只能猜测这在某种程度上是因为我正在使用线程池线程来卸载AppDomain
s。我就是不知道如何避免它
public partial class SomeService : ServiceBase
{
private Manager _appDomainManager;
protected override void OnStop()
{
_appDomainManager.Dispose();
}
}
public class Manager : IDisposable
{
public void Dispose()
{
Log.Debug("Disposing");
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
if (disposing)
{
// dispose managed resources
Parallel.For(0, appdomains.Length, UnloadAppDomian);
}
_disposed = true;
}
}
private UnloadAppDomain(int appDomainIndex);
public static class Parallel35
{
public static void For(int start, int end, Action<int> action)
{
var waitHandles = new WaitHandle[end - start];
for (int j = 0; j < waitHandles.Length; j++)
{
waitHandles[j] = new ManualResetEvent(false);
}
for (int i = start; i < end; i++)
{
int i1 = i - start;
ThreadPool.QueueUserWorkItem(
state =>
{
try
{
action((int) state);
}
finally
{
((ManualResetEvent) waitHandles[i1]).Set();
}
}, i);
}
WaitHandle.WaitAll(waitHandles);
}
}
公共部分类SomeService:ServiceBase
{
私人经理(appDomainManager),;
受保护的覆盖void OnStop()
{
_appDomainManager.Dispose();
}
}
公共类管理器:IDisposable
{
公共空间处置()
{
Log.Debug(“Disposing”);
处置(真实);
总干事(本);
}
受保护的虚拟void Dispose(bool disposing)
{
如果(_)返回;
如果(处置)
{
//处置托管资源
Parallel.For(0,appdomains.Length,UnloadAppDomian);
}
_这是真的;
}
}
私有UnloadAppDomain(int-appDomainIndex);
公共静态类35
{
用于(int开始、int结束、操作)的公共静态无效
{
var waitHandles=newwaithandle[end-start];
for(int j=0;j
{
尝试
{
动作((int)状态);
}
最后
{
((ManualResetEvent)waitHandles[i1]).Set();
}
},i);
}
WaitHandle.WaitAll(waitHandles);
}
}
尝试在单个后台任务中卸载所有AppDomain,而不是为每个AppDomain卸载一个后台任务,然后使用,以便SCM不会将您的服务标记为无响应。我将此作为一个bug跟踪到一个AppDomain
在退出时等待从未设置的WaitHandle
如果线程没有中止,例如,因为它正在执行
非托管代码,或者因为它正在执行finally块,所以
在中引发CannotUnloadAppDomainException的一段时间
最初调用卸载的线程
AppDomain
现在卸载速度相对较快,我的服务也很快停止。您是否尝试将调试器附加到您的服务上,以便使用“线程”窗口准确查看何时发生这种情况?顺便问一下,您是否尝试过在单个后台任务中卸载所有AppDomain,而不是在每个AppDomain中卸载一个后台任务?@PanosRontogiannis问题是,当我在单个后台线程中运行它时,OnStop
的执行时间太长。仍在调查中,对此问题存有怀疑。由于这条五年前的消息,我用可调用的清理例程替换了两个析构函数块,从而解决了我自己的异常,这样AppDomain在我清洗完成后,但在对象被销毁之前卸载。@David A.Gray您能分享一下您的解决方案吗?