Azure Function Service Bus Queue Trigger 환경에서 SkiaSharp을 이용 중에 AccessViolationException 이 발생했었습니다.
관련하여 Github에 올렸던 질문과 @evan-choi 님께서 제공해주신 해결책을 공유합니다.
오류 발생
opened 09:24PM - 06 Dec 16 UTC
type/bug
Hi! I'm using SkiaSharp for server side image generation and have run into an is… sue when Decoding many bitmaps at once on IIS.
Here's the error:
```
Application: w3wp.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
at SkiaSharp.SkiaApi.sk_codec_get_info(IntPtr, SkiaSharp.SKImageInfo ByRef)
at SkiaSharp.SKBitmap.Decode(SkiaSharp.SKCodec)
at SkiaSharp.SKBitmap.Decode(SkiaSharp.SKStream)
```
I'm not sure if this is because of memory constraints, because of thread safety or another reason I'm unaware of.
The code I have is this:
```c#
public static async Task LoadBitmap(RenderContext context, ILayoutElementHasUri element, Action<SKBitmap> handleBitmapAction) {
var uri = element.GetUriWithReplacements();
var bytes = await new LoadImage(uri, context).Execute();
// Limit the number of bitmaps decoding concurrently
await decodeBitmapThrottler.WaitAsync();
try
{
var bitmap = SKBitmap.Decode(bytes);
handleBitmapAction(bitmap);
if (bitmap != null)
{
bitmap.Dispose();
}
}
finally
{
decodeBitmapThrottler.Release();
}
}
```
My workaround has been to add a SemaphoreSlim, `decodeBitmapThrottler`, with a max count of 1, which increases the stability but sacrifices speed. As soon as I increase the count, I start getting System.AccessViolationException errors.
Any help or insight is appreciated! I also understand if this case is outside the goals of the project.
> VS bug [#735689](https://devdiv.visualstudio.com/DevDiv/_workitems/edit/735689)
오류 해결
opened 09:24PM - 06 Dec 16 UTC
type/bug
Hi! I'm using SkiaSharp for server side image generation and have run into an is… sue when Decoding many bitmaps at once on IIS.
Here's the error:
```
Application: w3wp.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
at SkiaSharp.SkiaApi.sk_codec_get_info(IntPtr, SkiaSharp.SKImageInfo ByRef)
at SkiaSharp.SKBitmap.Decode(SkiaSharp.SKCodec)
at SkiaSharp.SKBitmap.Decode(SkiaSharp.SKStream)
```
I'm not sure if this is because of memory constraints, because of thread safety or another reason I'm unaware of.
The code I have is this:
```c#
public static async Task LoadBitmap(RenderContext context, ILayoutElementHasUri element, Action<SKBitmap> handleBitmapAction) {
var uri = element.GetUriWithReplacements();
var bytes = await new LoadImage(uri, context).Execute();
// Limit the number of bitmaps decoding concurrently
await decodeBitmapThrottler.WaitAsync();
try
{
var bitmap = SKBitmap.Decode(bytes);
handleBitmapAction(bitmap);
if (bitmap != null)
{
bitmap.Dispose();
}
}
finally
{
decodeBitmapThrottler.Release();
}
}
```
My workaround has been to add a SemaphoreSlim, `decodeBitmapThrottler`, with a max count of 1, which increases the stability but sacrifices speed. As soon as I increase the count, I start getting System.AccessViolationException errors.
Any help or insight is appreciated! I also understand if this case is outside the goals of the project.
> VS bug [#735689](https://devdiv.visualstudio.com/DevDiv/_workitems/edit/735689)
SkiaSharp을 사용하시는 분들께 도움이 되면 좋겠습니다.
5개의 좋아요
요거 개인적으로 궁금한 부분인데, ManagedStream 사용이 핵심인 건가요…?
2개의 좋아요
그런 것 같습니다. 저도 왜 그런지는 파악하지 못했고 알려주신대로 수행한 부분이라…
기억은 잘 안나지만 어느 글에선가 SkManagedStream은 쓰지 않아도 된다고 SkiaSharp 개발자가 썼던 포스트를 봤던 것 같아서 그동안 SkManagedStream 없이 사용했었는데 @evan-choi 님께서 말씀해주신 건…imagebytes 스택이 해제되면서 unsafe memory에 영향이 생긴 것 같으니 SkMangedStream을 써보라고 하셨습니다.
SKBitmap.Decode에서드 중에서 ReadOnlySpan를 파라미터로 받는 메서드 오버로딩의 코드정의를 찾아서 보여주셨는데 아래와 같습니다. Decode자체 코드가 위험하게 생기긴 하셨다고 하셔서 SKManagedStream을 추천하셨습니다.
public static unsafe SKBitmap Decode(ReadOnlySpan<byte> buffer)
{
fixed (byte* numPtr = &buffer.GetPinnableReference())
{
using (SKData data = SKData.Create((IntPtr) (void*) numPtr, buffer.Length))
{
using (SKCodec codec = SKCodec.Create(data))
{
return SKBitmap.Decode(codec);
}
}
}
}
2개의 좋아요
오늘 SkiaSharp에 대해 또 AccessViolationException이 발생했고, 프로세스가 종료되는 문제가 발생했었습니다.
SkBitmap.GetPixel(); 을 호출하면서 Skia 내부의 API를 호출하는 과정에서 AccessViolationException이 발생했습니다. 데이터 자체가 잘못된 것이 들어와서 발생한 오류였지만 프로세스는 종료가 되지 않고 돌았어야 했기 때문에 아래 방법에서 도움을 받았습니다.
https://jacking.tistory.com/1411
@jacking75 감사합니다!!
4개의 좋아요
오래전 글인데 도움 되었다니 뿌듯합니다^^
고맙습니다~
4개의 좋아요
김예건
12월 27, 2022, 2:13오전
6
먼저 문제 해결한 내용을 공유해주셔서 감사합니다.
동일한 이슈를 겪는 듯하여 참고하고자 하였는데, @jacking75 님 블로그 글 링크가 접속이 안됩니다.
혹시 블로그가 더 이상 운영되지 않는 걸까요?
2개의 좋아요
혹시 티스토리 블로그라면 티스토리가 블로그를 정리해서 다 사라졌습니다 ;;;
현재는 https://jacking75.github.io/ 여기에 블로깅 하고 있습니다.
4개의 좋아요