【发布时间】:2014-09-30 20:08:17
【问题描述】:
我觉得肯定有比我想出的更好的解决方案;问题来了:
WPF 表单将调用 WCF 方法,该方法返回一个布尔值。调用本身不应该在 UI 线程上,调用的结果需要显示在表单上,所以返回应该被编组回 UI 线程。
在本例中,我创建了一个“ServiceGateway”类,表单将向该类传递一个在完成登录操作时要执行的方法。网关应使用 UI SynchronizationContext 调用此登录完成委托,该委托在从表单实例化网关时传递。 Login 方法使用 anon 调用对 _proxy.Login 的调用。异步委托,然后提供一个回调,该回调使用 UI SynchronizationContext 调用提供给网关(来自表单)的委托(“回调”参数):
[CallbackBehavior(UseSynchronizationContext = false)]
public class ChatServiceGateway : MessagingServiceCallback
{
private MessagingServiceClient _proxy;
private SynchronizationContext _uiSyncContext;
public ChatServiceGateway(SynchronizationContext UISyncContext)
{
_proxy = new MessagingServiceClient(new InstanceContext(this));
_proxy.Open();
_uiSyncContext = UISyncContext;
}
public void Login(String UserName, Action<bool> callback)
{
new Func<bool>(() => _proxy.Login(UserName)).BeginInvoke(delegate(IAsyncResult result)
{
bool LoginResult = ((Func<bool>)((AsyncResult)result).AsyncDelegate).EndInvoke(result);
_uiSyncContext.Send(new SendOrPostCallback(obj => callback(LoginResult)), null);
}, null);
}
从表单调用 Login 方法以响应按钮单击事件。
这很好用,但我怀疑我正在使用错误的方式使用 Login 方法;尤其是因为我必须对 WCF 服务的任何其他方法调用做同样的事情,而且它很丑陋。
我希望将异步行为和 ui 同步封装在网关中。在 WCF 端实现异步行为会更好吗?基本上,如果我可以更通用地为其他方法实现上述代码,或者是否有更好的方法,我很感兴趣。
【问题讨论】:
-
您应该能够使用基于
Task的异步 API 重新创建 WCF 客户端,这将大大清除这一点。
标签: c# wpf multithreading wcf