阻止线程上下文的流动
执行上下文的流动使得程序的执行效率下降很多,线程上下文的包装是一个成本较高的工作,而有时这样的包装并不是必需的。
这种情况下,程序员就需要手动地防止线程上下文的流动,常用的有下面两种方法:
使用定义在
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("权限测试没有通过");
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
输出结果
点击查看输出结果
已阻止文件访问
主线程权限测试:权限测试没有通过
子线程权限测试:权限测试通过
主线程权限测试:权限测试没有通过
子线程权限测试:权限测试通过
已恢复文件访问
主线程权限测试:权限测试通过
子线程权限测试:权限测试通过
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
注意
阻止线程执行上下文的流动会潜在的提高子线程的安全权限,这是因为主线程中的安全限制没有附件到子线程之上。
在设计的时候应充分考虑到这个问题,在保证不影响到系统安全性的前提下再着手提高效率。