【发布时间】:2012-12-07 07:29:53
【问题描述】:
我正在编写一个包装器,它允许我在任意 SynchronizationContext 上调用方法,例如,允许我将与网络相关的回调(例如 Socket.BeginReceive)排队到任意调度程序/处理程序,例如 UI 线程,或者我自己的为串行执行而设计的实现。 (避免需要同步数据结构 - 锁等)。
基本上是这样的:
..
public void BeginInvoke(MethodCall methodCall)
{
this.synchronizationContext.Post(this.SynchronizationContextCallback, methodCall);
}
private void SynchronizationContextCallback(Object methodCall)
{
(methodCall as MethodCall).Invoke();
}
..
aWindowsFormsSynchronizationContext 似乎一切正常,但是当抛出异常时(A System.Reflection.TargetInvocationException)我意识到 SendOrPostCallback 委托正在被动态调用(?!)这是相关代码(Microsoft Reference ) 来自System.Windows.Forms.Control.ThreadMethodEntry 类:
private static void InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
{
// We short-circuit a couple of common cases for speed.
//
if (tme.method is EventHandler)
{
if (tme.args == null || tme.args.Length < 1)
{
((EventHandler)tme.method)(tme.caller, EventArgs.Empty);
}
else if (tme.args.Length < 2)
{
((EventHandler)tme.method)(tme.args[0], EventArgs.Empty);
}
else
{
((EventHandler)tme.method)(tme.args[0], (EventArgs)tme.args[1]);
}
}
else if (tme.method is MethodInvoker)
{
((MethodInvoker)tme.method)();
}
else if (tme.method is WaitCallback)
{
Debug.Assert(tme.args.Length == 1,
"Arguments are wrong for WaitCallback");
((WaitCallback)tme.method)(tme.args[0]);
}
else
{
tme.retVal = tme.method.DynamicInvoke(tme.args);
}
}
似乎不支持SendOrPostCallback 委托,但有趣的是它的签名与WaitCallback 完全相同!或更一般地说,Action<Object>。这让我产生疑问,我在这里做错了吗?还是这是设计使然? (我的意思是在语言和框架级别上......)。显然.. 动态调用所有已调度的方法调用会明显变慢并且更难以调试? (到了我什至可能找不到可用的解决方案的地步?)。我在这里错过了什么?
【问题讨论】:
标签: c# .net winforms synchronization synchronizationcontext