简体   繁体   English

WCF异步调用的同步包装

[英]Synchronous wrapper for WCF asynchronous calls

We are calling WCF services asyncronously. 我们正在异步调用WCF服务。

public partial class ServiceClient : System.ServiceModel.ClientBase<MyService>, MyService 
{
    ......
}

ServiceClient _serviceclient;
void Getproducts(string filter, string augument, EventHandler<GetCompletedEventArgs> callback)
{
    _serviceclient.GetAsyncGetproducts(filter, argument, callback);
}

I want to the Getproducts function to be synchronous. 我希望Getproducts函数是同步的。 What is the best way to achieve this like the following 做到这一点的最佳方法是如下所示

void Getproducts(string filter, string augument, EventHandler<GetCompletedEventArgs> callback)
{
    _serviceclient.GetAsyncGetproducts(filter, argument, callback);
    //wait until callback comes back and return
}

EDIT: The proxy is providing any synchronous calls 编辑:代理提供任何同步调用

You cannot make synchronous networking requests in Silverlight from the UI thread. 无法通过 UI线程在Silverlight中发出同步网络请求 There's no going around that. 没有解决的办法。 Even if you try to trick the asynchronous methods into behaving synchronously, it will not work. 即使您试图欺骗异步方法使其行为同步,也将无法正常工作。 That's because if that were possible, the UI thread would be blocked, and the application would appear to be frozen. 这是因为,如果可能的话,UI线程将被阻止,并且该应用程序将被冻结。 This happens because the responses to networking requests in SL are always delivered to the UI thread; 发生这种情况是因为SL中对网络请求的响应始终传递到UI线程。 if you wait for it on the UI thread itself, then you create a deadlock. 如果在UI线程本身上等待它,则会创建死锁。

You essentially have two options: the preferred one is to actually go the asynchronous route. 从本质上讲,您有两种选择:首选的一种是实际使用异步路由。 It's hard at first, if you're only used to synchronous programming, but it's a very valuable skill to have. 如果您仅习惯于同步编程,那么一开始很难,但这是一项非常有价值的技能。 The other option is to make the call on a background thread. 另一个选择是在后台线程上进行调用。 I've tried it and it works, and some people have blogged about it , so you can try it as well. 我已经尝试过了,而且效果很好,有些人已经在博客上写了 ,因此您也可以尝试。 But AFAIK it's not officially supported. 但是AFAIK尚未得到正式支持。

Rather than just passing the callback parameter as the callback you'll want to assign your own callback that executes that method in addition to doing something else. 除了将回调参数作为回调传递外,您还需要分配自己的回调,该回调除了执行其他操作外还执行该方法。 You effectively just need to trigger an event of some sort. 您实际上仅需要触发某种事件。 I have demonstrated one way using tasks, but you could just as easily use an auto reset event or one of any number of other synchronization methods. 我已经演示了一种使用任务的方法,但是您可以轻松地使用自动重置事件或任何其他同步方法中的一种。

void Getproducts(string filter, string augument, EventHandler<GetCompletedEventArgs> callback)
{
    var tcs = new TaskCompletionSource<bool>();
    _serviceclient.GetAsyncGetproducts(filter, argument, args =>
    {
        callback(args);
        tcs.SetResult(true);
    });

    tcs.Task.Wait();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM