错误:ZLibStreamHandle类型的SafeHandle或CriticalHandle无法正确释放

时间:2016-04-18 20:29:15

标签: c# dispose gzipstream safehandle

我对流没有多少工作,所以我认为在我这里有一个编码错误。

   public static SqlBytes Compress(SqlBytes input)
    {
        byte[] data = (byte[])input.Value;
        using (MemoryStream memstream = new MemoryStream(data))
        {

            using (GZipStream zipped = new GZipStream(memstream, CompressionMode.Compress))
            {
                using (MemoryStream output = new MemoryStream()) 
                {
                    zipped.CopyTo(output);
                    return new SqlBytes(output.ToArray());
                }

            }

        }
    }

这是SQL Server 2012 CLR中的错误:

Msg 10323, Level 16, State 49, Line 1
Invalid user code has been identified by .Net Framework Managed Debug Assistant 'releaseHandleFailed':
A SafeHandle or CriticalHandle of type 'ZLibStreamHandle' failed to properly release the handle with value 0x0000000000000000. This usually indicates that the handle was released incorrectly via another means (such as extracting the handle using DangerousGetHandle and closing it directly or building another SafeHandle around it.)
   at System.Runtime.InteropServices.SafeHandle.InternalDispose()
   at System.IO.Compression.DeflaterZLib.Dispose(Boolean disposing)
   at System.IO.Compression.DeflateStream.Dispose(Boolean disposing)
   at System.IO.Stream.Close()
   at System.IO.Compression.GZipStream.Dispose(Boolean disposing)
   at System.IO.Stream.Close()
   at UserDefinedFunctions.Compress(SqlBytes input)
   at SQLCLR_Eval(IntPtr , IntPtr , IntPtr )

2 个答案:

答案 0 :(得分:5)

  <。>由.Net Framework托管调试助手

标识

这不是一个例外,只是来自MDA(托管调试助手)的通知。 CLR中集成的一小部分代码可检查常见的运行时故障。没有硬性异常的帮助很难诊断的那种。您只能在使用调试器时收到MDA通知。并且只有在启用MDA时,大多数都没有。

  

'releaseHandleFailed'

说出的MDA是检查正确使用SafeHandle的MDA。在这种特定情况下,它是ZLibStreamHandle class。实际的解压缩是由Zlib完成的,Zlib是一个用本机代码编写的开源库。 SafeHandles通常用于管理非托管资源,它们确保使用关键终结器发布此类资源。

releaseHandleFailed MDA值得注意的是,它通常会被关闭。它应该由编写SafeHandle类的程序员打开,比如编写ZLibStreamHandle的Microsoft程序员。因此,尽管通常会遇到此通知背后的错误,但几乎没有人会看到它。从未诊断过的错误永远不会得到修复。

  

无法正确释放值为0x0000000000000000

的句柄

这告诉你MDA警告完全是良性的。没有实际的非托管资源被不正确地释放,没有任何东西可以出错,底层句柄为空。当您按F5继续运行时,您的程序将保持愉快的开机状态。除了验证4.5框架中的更改的任何单元测试之外,MDA在单元测试中也不活跃。

然而, 出错了,不应该为null句柄创建ZLibStreamHandle对象。我没有看到在班级本身如何被弄糟的明显方式。当然,最初的Microsoft开发人员也没有看到它:)这个MDA通常由终结器触发。不是这里的情况,使用语句(又名Dispose()调用)触发了它。这是不寻常的,我怀疑你得到这个MDA之前你得到一个异常,告诉你在本机代码中出现了问题。发生的原因是 using 语句生成在报告异常之前执行的finally块。如果这是准确的,那么按F5就可以揭示真正的问题。

对于框架代码中的错误,您无法做任何其他事情。除了报告以便Microsoft可以修复它之外,请使用connect.microsoft.com告诉他们。

关闭MDA,这样你就可以像其他人一样高兴地忽略它。调试&gt;例外&gt;托管调试助理&gt;解开ReleaseHandleFailed。如果你勾选了它们,这是MDA意外启用的最典型方式,那么重置父项的复选框。

答案 1 :(得分:1)

就我而言,只是数据库在数据被压缩的列中有空字符串。当您仅使用SQL 2012压缩/解压缩空字符串时会出现问题。它在SQL 2008 / 2008R2中没有出现。希望这会有所帮助。