这不是一个重要的问题,但我想知道为什么Thread类公开一个属性来获取当前的Context(Thread.CurrentContext)和一个获取当前AppDomain(Thread.GetDomain())的方法.
知道Process> AppDomain> Context> Thread的层次结构,我的假设是在当前时间点知道线程的上下文,并且需要根据当前上下文搜索域.
但我想听听更明智的答案.谢谢!
我有一些日志代码,使用ContextBoundObject和ContextAttribute编写拦截方法调用.该代码基于代码项目示例.
这一切都运行良好,直到我们开始使用此库与利用异步和等待的代码.现在我们在运行代码时遇到了远程错误.这是一个重现问题的简单示例:
public class OhMyAttribute : ContextAttribute
{
public OhMyAttribute() : base("OhMy")
{
}
}
[OhMy]
public class Class1 : ContextBoundObject
{
private string one = "1";
public async Task Method1()
{
Console.WriteLine(one);
await Task.Delay(50);
Console.WriteLine(one);
}
}
Run Code Online (Sandbox Code Playgroud)
当我们调用时,Method1我们RemotingException在第二个上面得到以下内容Console.WriteLine:
Remoting cannot find field 'one' on type 'WindowsFormsApplication1.Class1'.
Run Code Online (Sandbox Code Playgroud)
有没有办法使用内置的C#方法来解决这个问题,还是我们必须看看像PostSharp这样的替代解决方案?
我们有一个相当大的现有代码库,用于构建在ASP.NET之上的各种web服务,并且该代码大量使用访问HttpContext.Current.User(包装为Client.User),我相当确定内部使用它[ThreadStatic]来为您提供环境范围.
我目前正在研究是否有可能我们开始以形式使用更多的异步代码,async/await但我很难找到如何使用[ThreadStatic]它.[ThreadStatic]由于其大量使用,实际上不可能消除对依赖的依赖.
我的理解是,当await命中时,代码的执行在那里停止,调用立即返回,并且设置延续以在异步代码返回时继续执行.同时,原始线程可以自由地用于其他事情,例如处理另一个请求.到目前为止我对它的理解.
我无法真正找到一个确定的答案HttpContext.Current.User是,在之前和之后是否保证是相同的await.
所以基本上:
HttpContext.Current.User = new MyPrincipal();
var user = HttpContext.Current.User;
await Task.Delay(30000);
// Meanwhile, while we wait for that lots of other requests are being handled,
// possibly by this thread.
Debug.Assert(object.ReferenceEquals(HttpContext.Current.User, user));
Run Code Online (Sandbox Code Playgroud)
这有Debug.Assert保证会成功吗?
如果另一个请求由与Task.Delay挂起的相同的线程处理,那么该请求将设置一个不同的HttpContext.Current.User,那么在调用continuation时以某种方式存储和恢复的先前状态是什么?
我可以想象的是,在幕后,[ThreadStatic]状态被保存为线程本身的某种字典,并且当一个线程返回到线程池后返回await该字典时,该字典在某处保持安全并且在设置回线程时它执行延续(或者在一个线程上,我不确定它是否一定是处理延续的同一个线程),可能是对屁股的鼓励和"去得到他们的男孩!",但最后部分可能只是我的想象力.
这有点准确吗?
更新:我试图将一个小试验放在一起尝试这个.到目前为止它似乎工作,并且断言没有因为数百个请求中的任何一个而失败.谁能验证测试是否有意义?