如何比较SynchronizationContext?似乎同一个调度程序在使用SynchronizationContext时可以创建不同的BeginInvoke。当我深入到这两个(不平等)上下文中时,我看到dispatcher线程ID是相同的,但它们并不相等。
public partial class MainWindow : Window
{
private SynchronizationContext contexta;
private SynchronizationContext contextb;
private SynchronizationContext contextc;
private SynchronizationContext contextd;
public MainWindow()
{
InitializeComponent();
contexta = SynchronizationContext.Current;
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
contextb = SynchronizationContext.Current;
Dispatcher.Invoke(() =>
{
contextc = SynchronizationContext.Current;
});
Dispatcher.BeginInvoke(new Action(() =>
{
contextd = SynchronizationContext.Current;
}));
Debug.Assert(contexta != contextb);
Debug.Assert(contexta == contextc); // fails... why?!?!?
Debug.Assert(contexta == contextd); // fails... why?!?!?
Debug.Assert(contextc == contextd); // fails... why?!?!?
} 也许这两个人不能一起用。我注意到这实际上很有效:
contexta.Send(new SendOrPostCallback((s) =>
{
contexte = SynchronizationContext.Current;
}), null);更新,但奇怪的是,它并不总是有效的。
public override void AddRange(IEnumerable<T> items)
{
if (SynchronizationContext.Current == _context)
{
base.AddRange(items);
}
else
{
_context.Send(new SendOrPostCallback((state) =>
{
AddRange(state as IEnumerable<T>);
}), items);
}
}例如,永远不会得到匹配的_context并永远继续下去。虽然不应该,但后一个例子--线程实际上是相同的,并且有一个上下文,但它是不同的。
Update2 Ok,我去工作了,但我真的觉得很不舒服。显然,当您发布或发送时,您的任务是从正确的线程运行的,但是如果您不是来自UI,似乎会生成一个新的SynchronizationContext。
public override void AddRange(IEnumerable<T> items)
{
if (SynchronizationContext.Current == _context)
{
base.AddRange(items);
}
else
{
_context.Post(new SendOrPostCallback((state) =>
{
if (SynchronizationContext.Current != _context)
SynchronizationContext.SetSynchronizationContext(_context); // called every time.. strange
AddRange(items);
}), null);
}
}看看这个:

“对直接调用方要求完全信任。此成员不能被部分信任或透明的代码使用。”:(
发布于 2013-05-29 23:51:01
我想你对BaseCompatibilityPreferences.ReuseDispatcherSynchronizationContextInstance感兴趣。
此设置指示是否为给定的Dispatcher对象使用单个SynchronizationContext实例。默认情况下,在.net 4之前为true,在.net 4.5中为false (这是LukeN观察到的行为更改)。
现在,如果您的目标只是直接调用,而不是调用.Send(),我会说:
在一般情况下,没有办法“比较”两个SynchronizationContexts,所以只需调用.Send()即可。无论如何,这不太可能是性能问题,请记住,早期优化首先是所有有害的->度量的根源。
https://stackoverflow.com/questions/13500030
复制相似问题