【问题标题】:Is ExecutionContext cleared after the thread is returned to thread pool?线程返回线程池后是否清除ExecutionContext?
【发布时间】:2014-07-01 08:11:44
【问题描述】:

写在docs

线程池重用线程时,不会清除里面的数据 线程本地存储或在标有 ThreadStaticAttribute 属性。因此,当一个方法检查 线程本地存储或标记有 ThreadStaticAttribute 属性,它找到的值可能会被留下 从早期使用的线程池线程开始。

然而它没有提到执行上下文。如何检查 ExecutionContext 是否被清除?

【问题讨论】:

  • 这是一个想象的问题,而不是真实的问题。没有发现与线程关联的 TLS 的机制。找回 ExecutionContext 当然不是问题。
  • @HansPassant 为什么会这么想?如果我尝试获取上下文数据并找到它,那么逻辑会话将在调用堆栈的某处设置。否则我需要设置这些数据。如果没有清除上下文,我可能会错误地处理这种情况。
  • .NET 在将执行上下文从原始线程流向 TP 线程方面投入了大量资金。对 CAS 和远程处理非常重要。只要你不能证明一个实际的问题,它就是一个想象的问题。

标签: .net threadpool executioncontext


【解决方案1】:

简而言之 - 是的。

  1. SynchronizationContext 未被捕获。
  2. LogicalCallContext 已清除。

_

using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;

namespace Tests
{
    [TestFixture]
    public class ExecutionContextFlowTest
    {
        [Test]
        public async Task Execute()
        {
            try
            {
                ThreadPool.SetMinThreads(2, 100);
                ThreadPool.SetMaxThreads(2, 100);

                var asyncLocal = new AsyncLocal<bool>();

                await Task.Run(
                    () =>
                        {
                            asyncLocal.Value = true;
                            CallContext.LogicalSetData("test", true);
                        });

                await Task.WhenAll(
                    Enumerable.Range(0, 10).Select(
                        _ => Task.Run(
                            () =>
                                {
                                    Assert.That(asyncLocal.Value, Is.False);
                                    Assert.That(CallContext.LogicalGetData("test"), Is.Null);
                                })).ToArray());
            }
            finally
            {
                ThreadPool.SetMinThreads(10, 100);
                ThreadPool.SetMaxThreads(100, 100);
            }
        }
    }
}

虽然我不确定SecurityContext

[ThreadStatic]ThreadLocal 不受 ExecutionContext 控制(并且未被清除)。

此外,在 .NET 源代码中,我发现了一个清理,它在项目执行完成后将 ExecutionContext 替换为以前的(空)。

【讨论】:

    猜你喜欢
    • 2015-07-31
    • 2016-10-20
    • 1970-01-01
    • 2023-03-12
    • 2014-03-10
    • 1970-01-01
    • 2011-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多