Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempted to access an unloaded AppDomain exception #164

Closed
hieudole opened this issue Apr 28, 2022 · 5 comments
Closed

Attempted to access an unloaded AppDomain exception #164

hieudole opened this issue Apr 28, 2022 · 5 comments

Comments

@hieudole
Copy link

Hello @kleisauke. I'm using your library in my website for image resizing and format converting. It performs very well, but sometimes I get AppDomainUnloadedException. I don't have any build/development on the website at that time.

System.AppDomainUnloadedException: Attempted to access an unloaded AppDomain.
   at NetVips.Internal.VipsOperation.Build(Operation operation)
   at NetVips.Operation.Call(String operationName, VOption kwargs, Image matchImage, Object[] args)
   at NetVips.Image.ExtractArea(Int32 left, Int32 top, Int32 width, Int32 height)
System.AppDomainUnloadedException: Attempted to access an unloaded AppDomain.
   at NetVips.Internal.VipsOperation.Build(Operation operation)
   at NetVips.Operation.Call(String operationName, VOption kwargs, Image matchImage, Object[] args)
   at NetVips.Image.HeifsaveTarget(Target target, Nullable`1 q, Nullable`1 lossless, Nullable`1 compression, Nullable`1 effort, Nullable`1 subsampleMode, Nullable`1 strip, Double[] background, Nullable`1 pageHeight)
   at NetVips.Image.HeifsaveStream(Stream stream, Nullable`1 q, Nullable`1 lossless, Nullable`1 compression, Nullable`1 effort, Nullable`1 subsampleMode, Nullable`1 strip, Double[] background, Nullable`1 pageHeight)

I need to restart my app pool every time this issue happens because NetVips can't work anymore. Do you know any reason that might relate to this issue?

I'm using:
.Net Framework 4.8
NetVips 2.1.0
NetVips.Native 8.12.2

@kleisauke kleisauke added the triage This issue is being investigated label May 1, 2022
@kleisauke
Copy link
Owner

kleisauke commented May 1, 2022

Hi @hieudole,

I'm not sure what's causing this. Are you seeing this exception with ASP.NET? Is this on Windows? I'm aware that ASP.NET may recycle the AppDomain, but as far as I know that ought to work without any problems.

I tried this test program to sanity check that:

Details
using System;
using System.IO;
using System.Reflection;

namespace ConsoleApp
{
    class Program
    {
        private static readonly string NetVipsAssembly =
            Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "NetVips.dll");

        static void Main()
        {
            for (var i = 0; i < 2; ++i)
            {
                // Create the domain
                Console.WriteLine($"[Program.Main] ===Pass #{i}===");
                Console.WriteLine($"[Program.Main] Creating the domain \"My Domain {i}\"");
                var domain = AppDomain.CreateDomain($"My Domain {i}");

                // Create a Proxy object in the new domain, where we want the assembly (and NetVips) to reside
                var type = typeof(Proxy);
                var proxy = (Proxy)domain.CreateInstanceAndUnwrap(
                    type.Assembly.FullName,
                    type.FullName);

                // Use the Proxy to call into the new assembly
                proxy.RunOperation(NetVipsAssembly);

                Console.WriteLine("[Program.Main] Before Domain Unload");
                AppDomain.Unload(domain);
                Console.WriteLine("[Program.Main] After Domain Unload");

                // Validate that the assembly does not exist anymore
                try
                {
                    Console.WriteLine(
                        $"[Program.Main] The Proxy object is valid ({proxy}). Unexpected domain unload behavior");
                }
                catch (Exception)
                {
                    Console.WriteLine("[Program.Main] The Proxy object is not valid anymore, domain unload complete.");
                }
            }

            Console.ReadKey();
        }

        class Proxy : MarshalByRefObject
        {
            public void RunOperation(string assemblyPath)
            {
                Console.WriteLine("[Proxy       ] In RunOperation");

                // Register domain unload event
                AppDomain.CurrentDomain.DomainUnload += OnDomainUnload;

                var assembly = Assembly.LoadFile(assemblyPath);
                var type = assembly.GetType("NetVips.Image");
                var method1 = type.GetMethod("Black");
                var method2 = type.GetMethod("WriteToFile");
                var instance = method1.Invoke(null, new object[] { 100, 100, 3 });
                method2.Invoke(instance, new object[] { "x.jpg", null });
            }

            private static void OnDomainUnload(object sender, EventArgs e)
            {
                Console.WriteLine(
                    $"[Proxy       ] In OnDomainUnload current domain = {AppDomain.CurrentDomain.FriendlyName}");
            }
        }
    }
}

Output:

[Program.Main] ===Pass #0===
[Program.Main] Creating the domain "My Domain 0"
[Proxy       ] In RunOperation
[Program.Main] Before Domain Unload
[Proxy       ] In OnDomainUnload current domain = My Domain 0
[Program.Main] After Domain Unload
[Program.Main] The Proxy object is not valid anymore, domain unload complete.
[Program.Main] ===Pass #1===
[Program.Main] Creating the domain "My Domain 1"
[Proxy       ] In RunOperation
[Program.Main] Before Domain Unload
[Proxy       ] In OnDomainUnload current domain = My Domain 1
[Program.Main] After Domain Unload
[Program.Main] The Proxy object is not valid anymore, domain unload complete.

But this works without any issues.

@hieudole
Copy link
Author

hieudole commented May 7, 2022

Thanks @kleisauke for investigating this issue. I have the same output with yours.
My app is running with ASP.NET on Windows. Perhaps the app pool was recycled while Netvips was running an operation.

@kleisauke
Copy link
Owner

I'm removing the triage label, without a reproduction it'll be hard to debug further.

@kleisauke kleisauke removed the triage This issue is being investigated label Jul 25, 2022
@kleisauke
Copy link
Owner

@hieudole Were you able to make any progress with this?

@hieudole
Copy link
Author

@kleisauke I'm closing this issue since I'm not able to reproduce it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants