C# WCF异步调用的同步包装器

C# WCF异步调用的同步包装器,c#,wcf,silverlight,asynchronous,synchronization,C#,Wcf,Silverlight,Asynchronous,Synchronization,我们正在异步调用WCF服务 public partial class ServiceClient : System.ServiceModel.ClientBase<MyService>, MyService { ...... } ServiceClient _serviceclient; void Getproducts(string filter, string augument, EventHandler<GetCompletedEventArgs> ca

我们正在异步调用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);
}
public部分类ServiceClient:System.ServiceModel.ClientBase,MyService
{
......
}
服务客户(ServiceClient);;
void Getproducts(字符串过滤器、字符串预兆、EventHandler回调)
{
_GetAsyncGetproducts(过滤器、参数、回调);
}
我希望Getproducts函数是同步的。实现这一目标的最佳方法是什么

void Getproducts(string filter, string augument, EventHandler<GetCompletedEventArgs> callback)
{
    _serviceclient.GetAsyncGetproducts(filter, argument, callback);
    //wait until callback comes back and return
}
void Getproducts(字符串过滤器、字符串预兆、EventHandler回调)
{
_GetAsyncGetproducts(过滤器、参数、回调);
//等待回调返回并返回
}

编辑:代理提供任何同步调用,而不仅仅是将callback参数作为回调传递,您需要分配自己的回调,该回调除执行其他操作外,还执行该方法。实际上,您只需要触发某种事件。我已经演示了使用任务的一种方法,但您也可以轻松地使用自动重置事件或任何其他同步方法

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();
}
void Getproducts(字符串过滤器、字符串预兆、EventHandler回调)
{
var tcs=new TaskCompletionSource();
_serviceclient.GetAsyncGetproducts(过滤器、参数、参数=>
{
回调(args);
tcs.SetResult(真);
});
Task.Wait();
}

除了执行其他操作外,您还需要分配自己的回调,以执行该方法,而不是将回调参数作为回调传递。实际上,您只需要触发某种事件。我已经演示了使用任务的一种方法,但您也可以轻松地使用自动重置事件或任何其他同步方法

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();
}
void Getproducts(字符串过滤器、字符串预兆、EventHandler回调)
{
var tcs=new TaskCompletionSource();
_serviceclient.GetAsyncGetproducts(过滤器、参数、参数=>
{
回调(args);
tcs.SetResult(真);
});
Task.Wait();
}

您无法从UI线程在Silverlight中发出同步网络请求。那是不可能的。即使您试图诱使异步方法同步运行,它也不会起作用。这是因为如果可能的话,UI线程将被阻塞,应用程序将被冻结。这是因为SL中对网络请求的响应总是传递到UI线程;如果在UI线程本身上等待,则会创建死锁


您基本上有两个选择:首选的一个是实际执行异步路由。如果您只习惯于同步编程,那么一开始很难做到,但这是一项非常有价值的技能。另一个选项是在后台线程上进行调用。我已经试过了,而且很有效,有些人已经试过了,所以你也可以试一下。但是,官方并不支持它。

您不能从UI线程在Silverlight中发出同步网络请求。那是不可能的。即使您试图诱使异步方法同步运行,它也不会起作用。这是因为如果可能的话,UI线程将被阻塞,应用程序将被冻结。这是因为SL中对网络请求的响应总是传递到UI线程;如果在UI线程本身上等待,则会创建死锁


您基本上有两个选择:首选的一个是实际执行异步路由。如果您只习惯于同步编程,那么一开始很难做到,但这是一项非常有价值的技能。另一个选项是在后台线程上进行调用。我已经试过了,而且很有效,有些人已经试过了,所以你也可以试一下。但是,官方不支持它。

为什么不使用代理为您生成的同步方法调用呢?代理不生成同步调用您控制代理的生成吗?使用svcutil.exe或使用Visual Studio的Web引用生成,同步调用是默认的。只使用它比包装异步调用容易得多。我们需要同步和异步调用同时存在于同一个应用程序中operation@RoyDictus嗯,没那么难,使异步操作同步总是比使同步操作异步容易。为什么不使用代理为您生成的同步方法调用呢?代理不生成同步调用您控制代理的生成吗?使用svcutil.exe或使用Visual Studio的Web引用生成,同步调用是默认的。只使用它比包装异步调用容易得多。我们需要同步和异步调用同时存在于同一个应用程序中operation@RoyDictus嗯,这并不难,而且使异步操作同步总是比使同步操作异步容易。我理解你的想法。我尝试了你的解决方案。但是,控件不会指向回调函数,应用程序会永远冻结+1,我没有预先提到silverlight客户端。不过,从答案中可以得到很好的信息。我理解你的想法。我尝试了你的解决方案。但是,控件不会指向回调函数,应用程序会永远冻结+1,我没有预先提到silverlight客户端。然而,从答案中可以得到很好的信息。