SynchronizationContext 的回调
Callbacks on SynchronizationContext
想弄清楚为什么 windows 实现回调的表单不起作用。
我想做什么:
- 按下按钮并调用服务。
- 服务回调表单(函数有 IsOneWay = true)
- 表单相应地更新 GUI
将 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;
}
}
字面上使用 SynchronizationContext 也不行
SynchronizationContext.Current.Send(_=> picBox.Visible = true, null);
第二个和第三个版本应该也可以吗?回调称为 OneWay,因此服务在回调后继续。
你的Form
class真的你的WCF服务客户端回调的实现吗,正如WCF所知(即不仅仅是您从 WCF 客户端委托给的东西)?如果不是,那么您将 [CallbackBehavior]
属性放在了错误的位置。正如文档所述:
The CallbackBehaviorAttribute must be applied to the class that implements the callback contract
如果是执行你的客户端回调,那么就没有好的Minimal, Complete, and Verifiable code example I'm afraid I wouldn't be able to say why the attribute isn't having the expected effect. But I would be able to say that, if that is indeed the case, your code is designed poorly. Combining your UI with your service client callback implementation violates a number of OOP principles for healthy code, but most importantly the Separation of Concerns原则。
就此而言:
SynchronizationContext.Current.Send(_=> picBox.Visible = true, null);
您不应该这样使用 SynchronizationContext
。 Current
属性 returns 当前 运行 线程的上下文。当您需要调用 Send()
时,检索上下文为时已晚。您需要在创建对象时将 SynchronizationContext.Current
存储在您希望执行 Send()
调用的委托的线程中(当然,该线程必须具有有用的上下文,例如在Winforms 程序的主 UI 线程)。
如果以上内容未能为您提供足够的信息来让您的代码正常工作,请通过提供可靠地重现问题的良好 MCVE 来改进问题。
想弄清楚为什么 windows 实现回调的表单不起作用。
我想做什么:
- 按下按钮并调用服务。
- 服务回调表单(函数有 IsOneWay = true)
- 表单相应地更新 GUI
将 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;
}
}
字面上使用 SynchronizationContext 也不行
SynchronizationContext.Current.Send(_=> picBox.Visible = true, null);
第二个和第三个版本应该也可以吗?回调称为 OneWay,因此服务在回调后继续。
你的Form
class真的你的WCF服务客户端回调的实现吗,正如WCF所知(即不仅仅是您从 WCF 客户端委托给的东西)?如果不是,那么您将 [CallbackBehavior]
属性放在了错误的位置。正如文档所述:
The CallbackBehaviorAttribute must be applied to the class that implements the callback contract
如果是执行你的客户端回调,那么就没有好的Minimal, Complete, and Verifiable code example I'm afraid I wouldn't be able to say why the attribute isn't having the expected effect. But I would be able to say that, if that is indeed the case, your code is designed poorly. Combining your UI with your service client callback implementation violates a number of OOP principles for healthy code, but most importantly the Separation of Concerns原则。
就此而言:
SynchronizationContext.Current.Send(_=> picBox.Visible = true, null);
您不应该这样使用 SynchronizationContext
。 Current
属性 returns 当前 运行 线程的上下文。当您需要调用 Send()
时,检索上下文为时已晚。您需要在创建对象时将 SynchronizationContext.Current
存储在您希望执行 Send()
调用的委托的线程中(当然,该线程必须具有有用的上下文,例如在Winforms 程序的主 UI 线程)。
如果以上内容未能为您提供足够的信息来让您的代码正常工作,请通过提供可靠地重现问题的良好 MCVE 来改进问题。