如何比较的SynchronizationContext? 看来,同样的调度员可以使用的BeginInvoke时创建不同的SynchronizationContext。 当我深入到两个(不等)环境中,我看到,调度线程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好吧,我得到它的工作,但我真的感到不舒服了。 显然,当你发布或发送,你的任务是从右边线运行,但如果你不是从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);
}
}
看看这个:
“需要对直接调用方完全信任。此成员不能由部分受信任的或透明的代码中使用。” :(