阻止线程上下文的流动
执行上下文的流动使得程序的执行效率下降很多,线程上下文的包装是一个成本较高的工作,而有时这样的包装并不是必需的。
这种情况下,程序员就需要手动地防止线程上下文的流动,常用的有下面两种方法:
使用定义在
System.Threading.ThreadPool
类型中的UnsafeQueueUserWorkItem
方法使用定义在
ExecutionContext
类型中的SuppressFlow
方法
示例代码
点击查看代码
cs
using System;
using System.IO;
using System.Security;
using System.Security.Permissions;
using System.Threading;
namespace SuppressContextFlow
{
class Program
{
private static string _testFIle = "D:\\TestContext.txt";
static void Main(string[] args)
{
try
{
// 建立测试文件
CreateTestFile();
// 现在修改安全上下文
// 阻止文件访问
FileIOPermission fip = new FileIOPermission(FileIOPermissionAccess.AllAccess, _testFIle);
fip.Deny();
Console.WriteLine("已阻止文件访问");
// 测试当前线程安全上下文
Console.Write("主线程权限测试:");
TestPermission(null);
// 建立一个子线程
Console.Write("子线程权限测试:");
// 使用 UnsafeQueueUserWorkItem 方法
ThreadPool.UnsafeQueueUserWorkItem(TestPermission, null);
Thread.Sleep(1000);
// 使用 SuppressFlow 方法
using (AsyncFlowControl afc = ExecutionContext.SuppressFlow())
{
Console.Write("主线程权限测试:");
TestPermission(null);
// 建立一个子线程
Console.Write("子线程权限测试:");
Thread son1 = new Thread(TestPermission);
son1.Start();
son1.Join();
}
// 现在修改安全上下文
// 恢复文件访问
SecurityPermission.RevertDeny();
Console.WriteLine("已恢复文件访问");
// 测试当前线程安全上下文
Console.Write("主线程权限测试:");
TestPermission(null);
// 建立一个子线程
Console.Write("子线程权限测试:");
Thread son2 = new Thread(TestPermission);
son2.Start();
son2.Join();
Console.Read();
}
finally
{
// 删除测试文件
DeleteTesfFile();
}
}
/// <summary>
/// 建立测试文件
/// </summary>
static void CreateTestFile()
{
if (!File.Exists(_testFIle))
{
using (FileStream fs = File.Create(_testFIle))
{
}
}
}
/// <summary>
/// 删除测试文件
/// </summary>
private static void DeleteTesfFile()
{
try
{
if (File.Exists(_testFIle))
{
File.Delete(_testFIle);
}
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// 尝试访问文件来测试安全上下文
/// </summary>
/// <param name="state"></param>
private static void TestPermission(object state)
{
try
{
// 尝试访问文件
File.GetCreationTime(_testFIle);
// 如果没有异常则测试通过
Console.WriteLine("权限测试通过");
}
catch (SecurityException)
{
// 表明没有权限访问
Console.WriteLine("权限测试没有通过");
}
}
}
}
输出结果
点击查看输出结果
已阻止文件访问
主线程权限测试:权限测试没有通过
子线程权限测试:权限测试通过
主线程权限测试:权限测试没有通过
子线程权限测试:权限测试通过
已恢复文件访问
主线程权限测试:权限测试通过
子线程权限测试:权限测试通过
注意
阻止线程执行上下文的流动会潜在的提高子线程的安全权限,这是因为主线程中的安全限制没有附件到子线程之上。
在设计的时候应充分考虑到这个问题,在保证不影响到系统安全性的前提下再着手提高效率。