Jam*_*mes 5 .net c# async-await
我一直在研究使用并在更改通知中AsyncLocal发现了ThreadContextChanged的属性。AsyncLocalValueChangedArgs<T>由于通常几乎不存在文档,
我对它的用途感到困惑(从文档中可以清楚地看出,只有在未显式更改异步值时才设置此值,但这是唯一清楚的事情)。
这里只有一个与此相关的其他问题(AsyncLocal Value Updated to null on ThreadContextChanged),它指的是调用者收到更改通知的情况,该值设置为 true 并且新值设置为 null,这是意外的。我更关心的是:
我的理解是,它AsyncLocal用于应与异步执行上下文一起携带的值,当连续在线程之间移动时根据需要跨越线程边界。
我可以理解在显式更改值时需要委托,但在未显式更改时更改值(似乎是此属性所指示的)对我来说似乎是无意义的。
在没有明确改变的情况下,值如何改变?上下文可以改变,但上下文中的值不应该改变——这就是类的全部要点。
上下文的改变根本不是值的改变——这是完全不同的事情。毕竟,该类包含多个值,并且添加附加值与现有值的突变是非常不同的操作,将它们放入同一个通知中而几乎没有任何解释来解释上述问题似乎是故意的令人困惑。
你有很多片面的问题和思考。然而,让我们退后一步看看基本面。
为什么这个属性存在
它只是让您确定是什么改变了该值。**反高潮**
在什么条件下您会收到此集合的通知,以及
IAsyncLocal.OnValueChanged当您深入等待堆栈并更改值时,会使用更新的值进行调用。然后,当您等待从堆栈中返回时,它会倒带,为您提供以前的值。
ThreadContextChanged只是让您知道该值是否因切换到不同的值ExecutionContext或有人设置该Value属性而发生变化。
当您收到此通知时,哪个调用和/或线程上下文处于活动状态。
我们看一下源码:
public T Value
{
...
set
{
ExecutionContext.SetLocalValue(this, value, m_valueChangedHandler != null);
}
}
Run Code Online (Sandbox Code Playgroud)
执行上下文.cs
internal static void SetLocalValue(IAsyncLocal local, object newValue, bool needChangeNotifications)
{
...
if (needChangeNotifications)
{
if (hadPreviousValue)
Contract.Assert(current.m_localChangeNotifications.Contains(local));
else
current.m_localChangeNotifications.Add(local);
local.OnValueChanged(previousValue, newValue, false);
}
}
Run Code Online (Sandbox Code Playgroud)
上下文切换后:
private static void OnContextChanged(ExecutionContext previous, ExecutionContext current)
{
previous = previous ?? Default;
foreach (IAsyncLocal local in previous.m_localChangeNotifications)
{
object previousValue;
object currentValue;
previous.m_localValues.TryGetValue(local, out previousValue);
current.m_localValues.TryGetValue(local, out currentValue);
if (previousValue != currentValue)
local.OnValueChanged(previousValue, currentValue, true);
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,事件是在值更改的上下文中引发的,其中可能包括新上下文或在更改后排队。
这有什么用?好吧,就我个人而言,我自己还没有使用过它,并且可能在框架的某个黑暗角落中实现它来解决特定问题,但我想它可能会在您尝试最小化锁定和同步的情况下有所帮助。
我从未见过这种方式的使用,正如您所指出的,在实际代码中很难找到具体的实现。然而,没有什么可以阻止你编写一些测试。
| 归档时间: |
|
| 查看次数: |
518 次 |
| 最近记录: |