我正在阅读和了解ThreadScheduler
以及有关任务的文章,并且遇到了MSDN examples中有关自己的ThreadSchedulers的函数ThreadPool.UnsafeQueueUserWorkItem
。在MSDN description about UnsafeQueueUserWorkItem中,有一个很大的警告,即该函数可能是一个安全漏洞,并且它“不会传播调用堆栈”。
唯一的链接是QueueUserWorkItem
- 从名称 - 似乎是“安全对应物”?但是没有提到任何关于调用堆栈的事情。
传播堆栈到底意味着什么?在工作开始之前复制它?为什么另一个线程需要调用线程的堆栈呢?我认为他们从一个新的空堆栈开始。毕竟,当线程函数返回时,它不会继续执行调度任务的函数,对吗?
答案 0 :(得分:22)
这是CAS,Code Access Security的实现细节。哪个可以检查线程是否有足够的权限来执行操作。只有代码在受限制的安全环境中运行,而不是以完全信任或在沙箱中运行时才重要。
使这项工作的管道很复杂,我只能近似它的工作方式。 ExecutionContext类是键,它确定代码运行的安全上下文。当以受限权限运行的线程启动另一个线程时,事情变得困难。显然,其他线程需要以与原始线程相同的限制运行。 CAS取决于能够执行堆栈遍历以发现限制。这在另一个线程上很难,它有自己的堆栈。
ExecutionContext.Capture()方法在此处发挥重要作用。它复制了调用线程的上下文,包括使堆栈遍历以创建发现的安全属性的“压缩”堆栈。然后,新线程将使用捕获的上下文运行。
ThreadPool.UnsafeQueueUserWorkItem()跳过Capture()调用。线程池线程将使用默认执行上下文运行。
这是一种优化,Capture()不是一种廉价的方法。在那种依赖于TP线程来匆忙完成工作的程序中,这很重要。想到一个Web服务器。此外,使用该方法的代码类型,例如,您在System.Net命名空间中的内部方法中使用它。
显然它不安全,它不会与原始线程的CAS限制一起运行。