1

我刚看到这个问题:

了解 .NET 的“SecurityAction”权限参数

我有一个问题。使用以下代码:

private void button1_Click(object sender, EventArgs e)
{
    Layer1();
    MessageBox.Show("OK");
}

private void Layer1()
{
    try
    {
        Layer2();
    }
    catch (SecurityException)
    {
        MessageBox.Show("Caught");
    }
    Layer2b();
}

private void Layer2()
{
    new System.Security.Permissions.FileIOPermission(PermissionState.Unrestricted).Deny();
    GC.Collect();
    Layer3();
}

private void Layer2b()
{
    Layer3();
}

[FileIOPermission(SecurityAction.LinkDemand, Write=@"C:\temp")]
private void Layer3()
{
    using (FileStream stream = new FileStream(@"C:\temp\test.txt", FileMode.Create))
    {
    }
}

为什么代码会在调用时产生安全异常Layer2?如何处理权限对象,我想垃圾收集器会销毁该对象,因为我没有对它的活动引用,但是代码说Caught,然后OK,所以很明显权限拒绝是有效的用于通过 Layer2 的呼叫。

是什么赋予了?我错过了什么?当谈到 .NET 中的安全/权限系统时,我承认自己是一个完全的初学者,所以如果这个问题真的很基本,请原谅我。

像这样的安全许可/拒绝会标记堆栈还是什么?否则,为什么对 Layer2b 无效?很明显,它是同一个线程,虽然它没有被垃圾收集杀死,但它在某个时候会被删除/销毁/清除。

4

2 回答 2

3

在 CodeAccessPermission 上调用 .Deny() 将导致 .NET 安全运行时在当前堆栈帧的安全对象上为该权限设置拒绝标志。因此,即使您在调用 .Deny() 之后调用 GC.Collect(),也没关系,权限将保持有效。权限对象只是 .NET 安全运行时部分在某个时间点(堆栈帧)的状态表示。

只需使用 .NET Reflector 即可了解更多信息。

于 2008-12-09T22:39:26.933 回答
0

乍一看,我猜想权限对象仍然在范围内,因为它是在方法内部定义的,所以在 Layer2 方法完成后它就超出了范围,从而允许您的应用程序的最后一行运行。

正如接受的答案所指出的,这是因为它在当前堆栈的范围内,与标准对象范围相关,您只是不管理引用。这是最好的记忆方式

于 2008-12-09T22:36:29.327 回答