.Net核心和同步上下文Thread.SetData [英] .Net core & SynchronizationContext & Thread.SetData

查看:186
本文介绍了.Net核心和同步上下文Thread.SetData的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,AspNetCore 没有 SynchronizationContext .

From what I know, AspNetCore doesn't have SynchronizationContext .

重新进入"请求上下文涉及许多家政任务,例如设置HttpContext.Current和当前线程的身份和文化.

That "re-entering" the request context involves a number of housekeeping tasks, such as setting HttpContext.Current and the current thread’s identity and culture.

因此,我创建了一个带有操作的简单.Net Core Api项目:

So I've created a simple .Net Core Api project with an action:

    [HttpGet]
    [Route("checkVar")]
    public async Task<IActionResult> checkVar()
    {
        Thread.SetData(Thread.GetNamedDataSlot("Random"),4);
        await Task.Delay(1000);
        var res = Thread.GetData(Thread.GetNamedDataSlot("Random"));
    }

让我惊讶的是, res 的值为 4 .我很惊讶,因为我相信 SetData 是同步上下文的一部分.(不应在asp.net核心中存在)

To my suruprise , res had a value of 4. I was surprised because I believe that SetData was part of the synchronization context. (which should not exist in asp.net core)

更多,当我使用 ConfigureAwait(false)时,在 res 中得到了 null .

More, when I used ConfigureAwait(false) , I got null in res.

所以现在我很困惑.因为 ConfigureAwait 在asp.net核心中不起作用

So now I'm confused. Because ConfigureAwait shouldn't have effect in asp.net core

问题:

如果asp.net核心没有SynchronizationContext,那么为什么 4 await 之后可用?为什么 ConfigureAwait 在非SynchronizationContext环境中会更改结果?

If asp.net core doesn't have a SynchronizationContext, then why did 4 was available after await ? why does the ConfigureAwait change the result in a non-SynchronizationContext environment?

推荐答案

我很惊讶,因为我相信SetData是同步上下文的一部分.(不应在asp.net核心中存在)

I was surprised because I believe that SetData was part of the synchronization context. (which should not exist in asp.net core)

否; SetData 是线程本地存储(TLS).因此,它与特定线程绑定.这与同步上下文无关.

No; SetData is thread-local storage (TLS). So it's tied to a specific thread. This doesn't have anything to do with synchronization contexts.

更多,当我使用ConfigureAwait(false)时,res的值为空.

More, when I used ConfigureAwait(false) , I got null in res.

根据运行此代码的时间,服务器的繁忙程度等,可以在具有或不具有 ConfigureAwait(false)的情况下获得 null 4 .

Depending on when you run this code, how busy the server is, etc., you could get null or 4 with or without ConfigureAwait(false).

如果asp.net核心没有SynchronizationContext,那么为什么在等待之后有4个可用?

If asp.net core doesn't have a SynchronizationContext, then why did 4 was available after await ?

这是特定于线程的值.ASP.NET Core上没有 SynchronizationContext ,并且您的代码将在任何可用的线程池线程上恢复.如果那个线程碰巧与开始该方法的线程相同,那么TLS将仍然存在,因为它用于该特定线程.

It's a thread-specific value. There's no SynchronizationContext on ASP.NET Core, and your code will resume on any available thread pool thread. If that thread happens to be the same thread that started that method, then the TLS is going to still be there because it's for that specific thread.

相同的行为实际上适用于ASP.NET pre-Core.在这种情况下,有一个 SynchronizationContext ,但是该上下文不与任何特定线程绑定.就像ASP.NET Core一样,ASP.NET pre-Core上的异步方法可以在任何可用的线程池线程上恢复,因此TLS数据在 await 之后可能存在或不存在.

The same behavior actually applies to ASP.NET pre-Core. In that case, there is a SynchronizationContext, but that context isn't tied to any particular thread. Just like ASP.NET Core, asynchronous methods on ASP.NET pre-Core can resume on any available thread pool thread, so TLS data may or may not be there after an await.

要用数据支持这一理论,请尝试在 await 之前和之后记录 Environment.CurrentManagedThreadId ,看看存在的数据与剩余的ID之间是否存在任何关联.一样.

To support this theory with data, try logging Environment.CurrentManagedThreadId before and after the await and see if there's any correlation between the data being present and the id remaining the same.

这篇关于.Net核心和同步上下文Thread.SetData的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆