使用约束执行区域

Pau*_*ulH 3 c# pinvoke handle cer

我有一个Visual Studio 2008 C#.NET 3.5应用程序P/Invokes一个接受文件句柄作为参数的本机方法.最初,我只是使用FileStream.SafeFileHandle.DangerousGetHandle()来获取文件句柄.但是,在启用FX COP之后,我收到了CA2001的警告.因此,经过一番研究后,我发现了"约束执行区域".这对我来说是新的,我还没有看到很多关于它的信息.我希望有经验的人可以看看并验证我是否已正确完成此操作.

class MyClass
{
    public static bool Write(string filename)
    {
        using (var fs = new System.IO.FileStream(filename, 
            System.IO.FileMode.Create, 
            System.IO.FileAccess.Write, 
            System.IO.FileShare.None))
        {
            bool got_handle;
            bool result;

            System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions();
            try { }
            finally
            {
                fs.SafeFileHandle.DangerousAddRef(ref got_handle);
                result = NativeMethods.Foo(fs.SafeFileHandle.DangerousGetHandle());
                if (got_handle)
                    fs.SafeFileHandle.DangerousRelease();   
            }

            return result;
        }
    }
}

internal sealed class NativeMethods
{
    [DllImport("mylib.dll",
        EntryPoint = "Foo",
        CallingConvention = CallingConvention.StdCall,
        CharSet = CharSet.Unicode,
        ExactSpelling = true, 
        SetLastError = true)]
    public static extern bool Foo(IntPtr hFile);
}
Run Code Online (Sandbox Code Playgroud)

谢谢,PaulH

Alo*_*aus 7

你在这里做了几件事.

  1. 在您执行安全代码时,执行finally块中的代码以防止ThreadAbortExceptions.

  2. 在try/finally技巧之前,你调用PrepareConstrainedRegions,除了检查是否存在足够的线程堆栈空间以确保至少可以进行一些方法调用以确保您的安全代码没有被StackOverFlowException防范时,基本上什么也没做.

所以是的,你的代码看起来像它可以得到的安全.在关于CERs 的官方文件中,有人说CLR确实认识到这个try/finally块,并采取了额外的措施.从我所看到的情况来看,除了在运行CER代码后OutOfMemoryExceptions也被延迟之外没有太大区别.

要确保您的代码符合您的期望,您应该为这些事情创建测试.

  • 堆栈耗尽
  • 内存不足
  • Thread.Abort的

编写可靠的代码真的很难,甚至大多数BCL类都没有像Joe Duffy解释的那样强硬.即使您的代码没有失败,BCL代码也可以.在BCL代码的主要部分能够以明确定义的方式处理这些极端条件之前,您不会获得太多额外的好处.

你的,Alois Kraus