SkiaSharp
SkiaSharp copied to clipboard
ArgumentException: "Cannot pass a GCHandle across AppDomains" while running ASP.NET MVC application in the IIS Server.
Description
We are using the SkiaSharp library to generate an image using SKData in an ASP.NET MVC application. When running the MVC application as multiple sites(Use same folder for all the sites) in the local IIS Server under one application pool (using the same pool name for all the site), we encounter an ArgumentException while browsing in IIS.
Note: Initially build the MVC application locally in Visual studio, then run in local IIS server. This exception "Cannot pass a GCHandle across AppDomains" occurs randomly while browsing it in the IIS server.
Reproduction sample Link Download the MVCSample.zip to replicate the problem.
Reference link for how to setup or install IIS server locally. https://learn.microsoft.com/en-us/aspnet/web-forms/overview/deployment/visual-studio-web-deployment/deploying-to-iis#install-iis
Reference link for how to add the ASP .NET MVC application as website on the IIS server by using the UI. Then create more sites like this with single MVC application. https://learn.microsoft.com/en-us/iis/application-frameworks/scenario-build-an-aspnet-website-on-iis/configuring-step-1-install-iis-and-asp-net-modules#to-add-an-aspnet-application-by-using-the-ui
Code
public ActionResult CreateImage()
{
//Open the file as Stream
FileStream imageData = new FileStream(Server.MapPath("~/App_Data/AdventureCycle.png"), FileMode.Open, FileAccess.Read);
MemoryStream outputStream = new MemoryStream();
using (SKData skImgData = SKData.Create(imageData))
{
skImgData.SaveTo(outputStream);
}
outputStream.Position = 0;
imageData.Close();
//Download Image file in the browser.
return File(outputStream, "image/png", "Output_Image.png");
}
Expected Behavior
SkiaSharp should create images properly without any errors when running an MVC application in multiple sites under one application pool in local IIS.
Actual Behavior
The following error we were faced randomly in the IIS server. Exception Details: System.ArgumentException: Cannot pass a GCHandle across AppDomains.
Stack Trace:
[ArgumentException: Cannot pass a GCHandle across AppDomains.
Parameter name: handle]
SkiaSharp.SKAbstractManagedStream.DisposeNative() in D:\a\1\s\binding\Binding\SKAbstractManagedStream.cs:52
SkiaSharp.SKNativeObject.Dispose(Boolean disposing) in D:\a\1\s\binding\Binding\SKObject.cs:287
SkiaSharp.SKManagedStream.Dispose(Boolean disposing) in D:\a\1\s\binding\Binding\SKManagedStream.cs:53
SkiaSharp.SKNativeObject.Dispose() in D:\a\1\s\binding\Binding\SKObject.cs:298
SkiaSharp.SKData.Create(Stream stream, Int64 length) in D:\a\1\s\binding\Binding\SKData.cs:141
MVCSample.Controllers.HomeController.CreateImage() in D:\SkiaSharpSample\MVCSample\MVCSample\Controllers\HomeController.cs:30
Version of SkiaSharp
2.88.3 (Current)
Last Known Good Version of SkiaSharp
2.88.2 (Previous)
IDE / Editor
Visual Studio (Windows)
Platform / Operating System
Windows
Platform / Operating System Version
No response
Devices
Basic Information: • SkiaSharp Version with issue: 2.88.7 • IDE: Visual Studio Professional 2022 Preview 17.9.0 Preview 1.0 • Platform: Windows (Windows 11 Enterprise) version: 23H2 • Target Frameworks: ASP .NET MVC Application of .NET Framework 4.8
Relevant Screenshots
Relevant Log Output
[ArgumentException: Cannot pass a GCHandle across AppDomains.
Parameter name: handle]
SkiaSharp.SKAbstractManagedStream.DisposeNative() in D:\a\1\s\binding\Binding\SKAbstractManagedStream.cs:52
SkiaSharp.SKNativeObject.Dispose(Boolean disposing) in D:\a\1\s\binding\Binding\SKObject.cs:287
SkiaSharp.SKManagedStream.Dispose(Boolean disposing) in D:\a\1\s\binding\Binding\SKManagedStream.cs:53
SkiaSharp.SKNativeObject.Dispose() in D:\a\1\s\binding\Binding\SKObject.cs:298
SkiaSharp.SKData.Create(Stream stream, Int64 length) in D:\a\1\s\binding\Binding\SKData.cs:141
MVCSample.Controllers.HomeController.CreateImage() in D:\SkiaSharpSample\MVCSample\MVCSample\Controllers\HomeController.cs:30
Code of Conduct
- [X] I agree to follow this project's Code of Conduct
Hi team,
Any update in this?
Regards, Akash.
I am also facing same problem. Any workaround or solution would be helpful.
Hi Team, Any update on this issue? Any workaround or solution would be helpful, as we have been waiting for a while.
having similar issue and it crashed IIS every time.
Hi Team, Any update on this issue? Any workaround or solution would be helpful, as we have been waiting for a while.
I am not too familiar with the way IIS works, but SkiaSharp is using GCHandles to get direct access to memory for drawing and processing pixels. Is there a way to mark a controller as not usable across app domains? Maybe the image logic needs to be in a separate place that can be marked or controlled as such?
I did a quick search and this came up: https://github.com/cefsharp/CefSharp/issues/351
If anyone has more info on IIS and how this would work, please let me know.