UnsafeQueueUserWorkItem以及"不传播调用堆栈"究竟是什么意思?

Imi*_*Imi 19 c# .net-4.0 task-parallel-library

我正在阅读和学习有关ThreadSchedulerTasks的文章和文章,并且遇到了ThreadPool.UnsafeQueueUserWorkItem一个关于自己的ThreadSchedulers 的MSDN示例中使用的函数.在关于UnsafeQueueUserWorkItem的MSDN 描述中,有一个很大的警告,即该函数可能是一个安全漏洞,并且它" 不会传播调用堆栈 ".

唯一的联系是QueueUserWorkItem- 从名称 - 似乎是"安全的对应物"?但是没有提到任何关于调用堆栈的事情.

传播堆栈到底意味着什么?在工作开始之前复制它?为什么另一个线程需要调用线程的堆栈呢?我认为他们从一个新的空堆栈开始.毕竟,当线程函数返回时,它不会继续执行调度任务的函数,对吧?

Han*_*ant 24

它是CAS,Code Access Security的实现细节.哪个可以检查线程是否有足够的权限来执行操作.只有代码在受限制的安全环境中运行,而不是以完全信任或在沙箱中运行时才重要.

使这项工作的管道很复杂,我只能近似它的工作方式.ExecutionContext类是键,它确定代码运行的安全上下文.当以受限权限运行的线程启动另一个线程时,事情变得困难.显然,其他线程需要以与原始线程相同的限制运行.CAS取决于能够执行堆栈遍历以发现限制.这在另一个线程上很难,它有自己的堆栈.

ExecutionContext.Capture()方法在此处执行重要角色.它复制了调用线程的上下文,包括使堆栈遍历以创建发现的安全属性的"压缩"堆栈.然后,新线程将使用捕获的上下文运行.

ThreadPool.UnsafeQueueUserWorkItem()跳过Capture()调用.线程池线程将使用默认执行上下文运行.

这是一种优化,Capture()不是一种廉价的方法.在那种依赖于TP线程来匆忙完成工作的程序中,这很重要.想到一个Web服务器.此外,使用该方法的代码类型,例如,您可以在System.Net命名空间中的内部方法中看到它.

显然它是不安全的,它不会与原始线程的CAS限制一起运行.

  • 顺便说一句.. 在我测试的机器上(大约 3GHz 库存 X86),结果显示每个调度调用的差异在“几十纳秒”范围内。我当然可以接受_那个_。(尽管我们最终使用了一些完全不同的解决方案..;)) (2认同)