Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 卸载appdomain时出错。(HRESULT的异常:0x801315),Windows服务内部_C#_Exception_Appdomain - Fatal编程技术网

C# 卸载appdomain时出错。(HRESULT的异常:0x801315),Windows服务内部

C# 卸载appdomain时出错。(HRESULT的异常:0x801315),Windows服务内部,c#,exception,appdomain,C#,Exception,Appdomain,我在windows服务中收到此错误。 这与我之前在问题中讨论的服务相同 代码修改为使用Parallel.ForEach(我自己的版本,因为这是一个3.5 windows服务)。并行使用的原因是卸载每个域花费的时间太长,并行运行它们应该会更快(看起来是即使只有一个线程在执行每次卸载?!) 根据其他帖子,我只能猜测这在某种程度上是因为我正在使用线程池线程来卸载AppDomains。我就是不知道如何避免它 public partial class SomeService : ServiceBase {

我在windows服务中收到此错误。 这与我之前在问题中讨论的服务相同

代码修改为使用
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您能分享一下您的解决方案吗?