我刚看到这个问题:
Understanding .NET’s “SecurityAction” parameter for permissions
我有一个问题。使用以下代码:
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 ,然后好的,很明显,权限拒绝对于通过Layer2的调用有效。
是什么给出的?我错过了什么?我承认,当谈到.NET中的安全/权限系统时,我是一个初学者,所以请原谅我,如果这个问题真的很基础。
这样的安全权限/拒绝是否标记了堆栈或其他内容?否则,为什么它不对Layer2b有效?它是同一个线程,很清楚,虽然它没有被垃圾收集杀死,但它会在某些时候被删除/销毁/清理掉。
答案 0 :(得分:3)
在CodeAccessPermission上调用.Deny()将导致.NET安全运行时在安全对象上为该权限的当前堆栈帧设置拒绝标志。 因此,即使在调用.Deny()之后调用GC.Collect(),它也没关系,权限将保持有效。权限对象只是某个时间点(堆栈帧)中.NET安全性运行时部分状态的表示。
只需使用.NET Reflector了解更多信息。
答案 1 :(得分:0)
第一眼看,我猜测权限对象仍在范围内,因为它是在方法内定义的,它在Layer2方法完成后超出了范围,从而允许应用程序的最后一行运行
如接受的答案所述,这是因为它在当前堆栈的范围内,与标准对象范围相关,您只是不管理引用。这是记住它的最佳方式