试图解决为什么实现回调的Windows窗体无法正常工作。
我想做的事情:
将UseSynchronizationContext设为false并在GUI成员上调用Invoke可以正常工作:
[CallbackBehavior(UseSynchronizationContext = false)]
public class DeliveryClient : System.Windows.Forms.Form, ICallback
{
public void ServiceCallback(string system, string state, string extraInfo)
{
if (state == "start")
{
Invoke((MethodInvoker)delegate { picBox.Visible = true; });
}
else
{
Invoke((MethodInvoker)delegate { picBox.Visible = false; });
}
}
}
但是UseSynchronizationContext = true并且直接调用成员不会:
[CallbackBehavior(UseSynchronizationContext = true)]
public class DeliveryClient : System.Windows.Forms.Form, ICallback
{
public void ServiceCallback(string system, string state, string extraInfo)
{
if (state == "start")
{
picBox.Visible = true;
}
else
{
picBox.Visible = false;
}
}
也没有按字面意思使用SyynchronizationContext
SynchronizationContext.Current.Send(_=> picBox.Visible = true, null);
第二版和第三版是否也有效?回调称为OneWay,因此服务在回调后继续。
答案 0 :(得分:1)
您的Form
类是否真的是WCF服务客户端回调的实现,正如WCF所知(即不仅仅是您从WCF委托的内容)客户)?如果没有,那么您已将[CallbackBehavior]
属性放在错误的位置。正如文档所述:
必须将CallbackBehaviorAttribute应用于实现回调协定的类
如果是你的客户回调的实现,那么没有好Minimal, Complete, and Verifiable code example我害怕我不能说出为什么该属性没有预期的效果。但我会能够说,如果情况确实如此,那么你的代码设计得很糟糕。将您的UI与服务客户端回调实现相结合违反了许多针对健康代码的OOP原则,但最重要的是Separation of Concerns原则。
就此而言:
SynchronizationContext.Current.Send(_=> picBox.Visible = true, null);
那不是你应该如何使用SynchronizationContext
。 Current
属性返回当前运行的线程的上下文。当您需要致电Send()
时,检索上下文为时已晚。您需要在创建对象时存储SynchronizationContext.Current
,在您希望Send()
调用委托的线程中执行(当然,该线程必须具有有用的上下文,例如在Winforms程序的主要UI线程。)
如果上述内容没有为您提供足够的信息以使您的代码正常工作,请通过提供可靠地重现问题的良好MCVE来改进问题。