SharpDX.Direct2D1.Bitmap dispose crash on windows 8

0

I am getting a strange crash when disposing a several SharpDx Bitmaps after the application is finished with them. The exception seems to be uncatchable and goes all the way to crash IIS. It doesn't happen every time and doesn't occur at all on windows 7.

Using DebugDiag for a crash report produces:

Type of Analysis Performed   Crash Analysis 
Machine Name   My-Machine-Name 
Operating System   Unexpected  
Number Of Processors   2 
Process ID   9556 
Process Image   c:\Windows\System32\inetsrv\w3wp.exe 
System Up-Time   3 day(s) 02:43:33 
Process Up-Time   00:00:54 

In w3wp__App Pool__PID__9556__Date__10_13_2014__Time_10_02_32AM__26__Second_Chance_Exception_C0000409.dmp the assembly instruction at MSVCR120_CLR0400!abort+34 in C:\Windows\System32\MSVCR120_CLR0400.dll from Microsoft Corporation has caused an unknown exception (0xc0000409) on thread 21

Thread 21 - System ID 6816
Entry point   clr!Thread::intermediateThreadProc 
Create time   10/13/2014 10:01:53 AM 
Time spent in user mode   0 Days 0:0:14.937 
Time spent in kernel mode   0 Days 0:0:0.250 

.NET Call Stack

Function 
System.Runtime.InteropServices.Marshal.Release(IntPtr) 
System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr, System.Web.RequestNotificationStatus ByRef) 
System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr, System.Web.RequestNotificationStatus ByRef) 

Full Call Stack

Function
MSVCR120_CLR0400!abort+34
MSVCR120_CLR0400!purecall+29
WindowsCodecs!CExternalStream::HrClose+44
WindowsCodecs!CExternalStream::~CExternalStream+23
WindowsCodecs!CExternalStream::`vector deleting destructor'+14
WindowsCodecs!CMILCOMBase::InternalRelease+29
d2d1!BitmapRealization::~BitmapRealization+2c0
d2d1!RefCountedObject<BitmapRealization,LockingRequired,DeleteOnZeroReference>::`vector deleting destructor'+29 
d2d1!RefCountedObject<BitmapRealization,LockingRequired,DeleteOnZeroReference>::Release+31
d2d1!D2DBitmap::~D2DBitmap+d7
d2d1!ComObject<D2DBitmap,type_list<ID2D1Bitmap,type_list<ID2DImageStreamSource,type_list<DXCapture::IDxObservedObject,type_list<ID2D1Bitmap1,type_list<ID2D1Image,type_list<DXCapture::IDxObservedObject,type_list<ID2D1Resource,type_list<DXCapture::IDxObservedObject,null_type> > > > > > > >,LockingRequired,RefCountedObject<D2DBitmap,LockingRequired,LockFactoryOnReferenceReachedZero> >::`vector deleting destructor'+14
d2d1!LockFactoryOnReferenceReachedZero::ReferenceReachedZero<RefCountedObject<D2DBitmap,LockingRequired,LockFactoryOnReferenceReachedZero> >+48
d2d1!RefCountedObject<D2DBitmap,LockingRequired,LockFactoryOnReferenceReachedZero>::Release+22
clr!SafeRelease+af
clr!MarshalNative::Release+9a
0x00007ff8`19e35616
0x00007ff8`19e35592
0x00007ff8`19e354b6
0x00007ff8`1a08f40b
0x00007ff8`1a08ea68
0x00007ff8`1a002150
0x00007ff8`1a001d62
0x00007ff8`19ffd941
0x00007ff8`19ffc990
0x00007ff8`19ffc321
0x00007ff8`19923841
0x00007ff8`199236e7
0x00007ff8`1991e9e6
System_Web_ni+2f6221
System_Web_ni+2bd495
System_Web_ni+2dab5a
System_Web_ni+2bd6a3
System_Web_ni+2b75de
System_Web_ni+2c0561
System_Web_ni+2bff92
System_Web_ni+a15a41
clr!UMThunkStub+6e
webengine4!W3_MGD_HANDLER::ProcessNotification+78
webengine4!W3_MGD_HANDLER::DoWork+34f
webengine4!RequestDoWork+34e
webengine4!CMgdEngHttpModule::OnExecuteRequestHandler+21
iiscore!NOTIFICATION_CONTEXT::RequestDoWork+224
iiscore!NOTIFICATION_CONTEXT::CallModulesInternal+198
iiscore!NOTIFICATION_CONTEXT::CallModules+36
iiscore!NOTIFICATION_MAIN::DoWork+4b4
iiscore!W3_CONTEXT_BASE::IndicateCompletion+97
webengine4!MgdIndicateCompletion+60
System_Web_ni+36956b
System_Web_ni+2c074f
System_Web_ni+2bff92
System_Web_ni+a15a41
clr!UM2MThunk_WrapperHelper+43
clr!UM2MThunk_Wrapper+5a
clr!Thread::DoADCallBack+13c
clr!UM2MDoADCallBack+91
clr!UMThunkStub+26d
webengine4!W3_MGD_HANDLER::ProcessNotification+78
webengine4!ProcessNotificationCallback+42
clr!UnManagedPerAppDomainTPCount::DispatchWorkItem+134
clr!ThreadpoolMgr::ExecuteWorkRequest+64
clr!ThreadpoolMgr::WorkerThreadStart+2b6
clr!Thread::intermediateThreadProc+7d
kernel32!BaseThreadInitThunk+d
ntdll!RtlUserThreadStart+1d

Can anyone make sense of this crash? Or anyone have any tips as to how I might solve this issue?

c#
iis
windows-8
directx
sharpdx
asked on Stack Overflow Oct 14, 2014 by Kevin Langille • edited Oct 24, 2014 by Kevin Langille

2 Answers

0

Finally got a chance to try @osexpert's suggestion.

I added a new class to store the stream and the various classes that use the stream (WIC.BitmapDecoder, WIC.BitmapFrameDecode, WIC.FormatConverter), so they could be disposed of in the correct order when the program is finished with the bitmap.

This has stopped the error from appearing. Unfortunately I still don't know why it was only occurring on Win8. As the error occurred sort of randomly its possible the timing was different enough on Win7 so the error didn't happen.

answered on Stack Overflow Jan 4, 2015 by Kevin Langille
0

i have fix this problem use your suggestion. this is my old code, it will crash when i dispose it randomly.

internal class Direct2DTexture2D : ITexture2D, ID2DResource
{
    internal SharpDX.Direct2D1.Bitmap Texture2D;

    internal Direct2DTexture2D(IRenderTarget InRenderTarget, Bitmap InBitmap)
    {
        Direct2DResourceManager.OnResourceCreate(this);
        Direct2DRenderTarget RT = InRenderTarget as Direct2DRenderTarget;

        Texture2D = CreateFromBitmap(RT.RenderTarget, InBitmap);
    }

    internal Direct2DTexture2D(IRenderTarget InRenderTarget, string InFilePath)
    {
        Direct2DResourceManager.OnResourceCreate(this);
        Direct2DRenderTarget RT = InRenderTarget as Direct2DRenderTarget;

        var bitmap = (System.Drawing.Bitmap)System.Drawing.Image.FromFile(InFilePath);

        Texture2D = CreateFromBitmap(RT.RenderTarget, bitmap);
    }

    private SharpDX.Direct2D1.Bitmap CreateFromBitmap(SharpDX.Direct2D1.RenderTarget InRenderTarget, Bitmap InBitmap)
    {

        using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
        {
            InBitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);

            using (SharpDX.WIC.BitmapDecoder bitDecorder =
                new SharpDX.WIC.BitmapDecoder(Direct2DDrawingSystem.instance.ImagingFactory,
                ms,
                SharpDX.WIC.DecodeOptions.CacheOnDemand)
                )
            {
                using (SharpDX.WIC.BitmapFrameDecode bfDecode = bitDecorder.GetFrame(0))
                {
                    using (SharpDX.WIC.FormatConverter fConverter = new SharpDX.WIC.FormatConverter(Direct2DDrawingSystem.instance.ImagingFactory))
                    {
                        fConverter.Initialize(bfDecode, SharpDX.WIC.PixelFormat.Format32bppPBGRA, SharpDX.WIC.BitmapDitherType.None, null, 0, SharpDX.WIC.BitmapPaletteType.Custom);

                        return SharpDX.Direct2D1.Bitmap.FromWicBitmap(InRenderTarget, fConverter);
                    }
                }
            }
        }

    }

    public float width { get { return Texture2D.Size.Width; } }

    public float height { get { return Texture2D.Size.Height; } }

    public void Dispose()
    {
        Direct2DResourceManager.OnResourceDestroy(this);

        if (Texture2D!=null)
        {
            Texture2D.Dispose();
            Texture2D = null;
        }            
    }
}

this code use using command at around the code. the underline code works well on all platform, you can see it:

 internal class Direct2DTexture2D : ITexture2D, ID2DResource
{
    private System.IO.MemoryStream MemStream;
    private SharpDX.WIC.BitmapDecoder BitDecorder;
    private SharpDX.WIC.BitmapFrameDecode BFDecorde;
    private SharpDX.WIC.FormatConverter fConverter;

    internal SharpDX.Direct2D1.Bitmap Texture2D;

    internal Direct2DTexture2D(IRenderTarget InRenderTarget, Bitmap InBitmap)
    {
        Direct2DResourceManager.OnResourceCreate(this);
        Direct2DRenderTarget RT = InRenderTarget as Direct2DRenderTarget;

        CreateFromBitmap(RT.RenderTarget, InBitmap);
    }

    internal Direct2DTexture2D(IRenderTarget InRenderTarget, string InFilePath)
    {
        Direct2DResourceManager.OnResourceCreate(this);
        Direct2DRenderTarget RT = InRenderTarget as Direct2DRenderTarget;

        var bitmap = (System.Drawing.Bitmap)System.Drawing.Image.FromFile(InFilePath);

        CreateFromBitmap(RT.RenderTarget, bitmap);
    }

    private void CreateFromBitmap(SharpDX.Direct2D1.RenderTarget InRenderTarget, Bitmap InBitmap)
    {
        MemStream = new System.IO.MemoryStream();
        InBitmap.Save(MemStream, System.Drawing.Imaging.ImageFormat.Png);
        BitDecorder = new SharpDX.WIC.BitmapDecoder(Direct2DDrawingSystem.instance.ImagingFactory,
                            MemStream,
                            SharpDX.WIC.DecodeOptions.CacheOnDemand);

        BFDecorde = BitDecorder.GetFrame(0);

        fConverter = new SharpDX.WIC.FormatConverter(Direct2DDrawingSystem.instance.ImagingFactory);

        fConverter.Initialize(BFDecorde, SharpDX.WIC.PixelFormat.Format32bppPBGRA, SharpDX.WIC.BitmapDitherType.None, null, 0, SharpDX.WIC.BitmapPaletteType.Custom);

        Texture2D = SharpDX.Direct2D1.Bitmap.FromWicBitmap(InRenderTarget, fConverter);
    }

    public float width { get { return Texture2D.Size.Width; } }

    public float height { get { return Texture2D.Size.Height; } }

    public void Dispose()
    {
        Direct2DResourceManager.OnResourceDestroy(this);

        if (Texture2D!=null)
        {
            Texture2D.Dispose();
            Texture2D = null;
        }            

        if(fConverter!=null)
        {
            fConverter.Dispose();
            fConverter = null;
        }

        if(BFDecorde != null)
        {
            BFDecorde.Dispose();
            BFDecorde = null;
        }

        if(BitDecorder!=null)
        {
            BitDecorder.Dispose();
            BitDecorder = null;
        }

        if(MemStream!=null)
        {
            MemStream.Dispose();
            MemStream = null;
        }
    }
}

this code show how to create a direct2d image from a C# bitmap by sharpdx.

answered on Stack Overflow Jun 25, 2018 by Hikari

User contributions licensed under CC BY-SA 3.0