您如何等待/加入从Silverlight调用的WCF Web服务?

时间:2008-11-24 15:13:58

标签: wcf silverlight web-services

如果您从Silverlight调用Web服务,请执行以下操作:

MyServiceClient serviceClient = new MyServiceClient();
void MyMethod()
{
  serviceClient.GetDataCompleted += new EventHandler<GetDataCompletedEventArgs>(serviceClient_GetDataCompleted);
  serviceClient.GetDataAsync();

  // HOW DO I WAIT/JOIN HERE ON THE ASYNC CALL, RATHER THAN BEING FORCE TO LEAVE THIS METHOD?

}

我宁愿等待/加入“MyMethod”中的asych服务线程,而不是在调用“GetDataAsync”后离开“MyMethod”,这样做的最佳方式是什么?

谢谢, 杰夫

5 个答案:

答案 0 :(得分:4)

不,你不能这样做。你最终陷入僵局。 GetDataCompleted由mainthreed调用。同样的人在WaitOne等着。

答案 1 :(得分:1)

我不得不问;为什么?关键是为您的用户提供流畅的体验,等待Web服务调用不一定会这样做。我想你想要在加载Silverlight控件之前加载完整的内容块。在这种情况下,我会转向缓存内容而不是强迫客户端无限期地等待。

答案 2 :(得分:0)

要执行此操作,您将在类中使用ManualResetEvent(类级别变量),然后等待它。

void MyMethod()
{
  wait = new ManualResetEvent(false);
  // call your service
  wait.WaitOne();
  // finish working
}

并在您的事件处理程序代码中

void serviceClient_GetDataCompleted(...)
{
  // Set values you need from service
  wait.Set();
}

答案 3 :(得分:0)

你也可以使用lambda和closure来获得类似的行为:

serviceClient.GetDataCompleted += (s,e) =>
{
  // Your code here
};
serviceClient.GetDataAsync();

答案 4 :(得分:0)

如果您有一个基类提供构建WCF通道的机制,那么它可以用于为异步调用构建BeginX / EndX方法。

public class ServiceFooCoordinator : CoordinatorBase<IServiceFoo>
{
    public IAsyncResult BeginMethodFoo ()
    {
        IAsyncResult ar = null;
        IServiceFoo channel = null;
        channel = _factory.GetChannel();

        Begin( channel, () => ar = channel.BeginMethodFoo( null, channel ) );
        return ar;
    }

    public Bar[] EndMethodFoo ( IAsyncResult ar )
    {
        IServiceFoo channel = null;
        channel = _factory.GetChannel();
        return channel.EndMethodFoo( ar );
    }
}

然后可以在方法中使用:

 ServiceFooCoordinator _coordinator;

 var asyncResult = _coordinator.BeginMethodFoo();
 try
 {
   var result = _coordinator.EndMethodFoo( asyncResult );
 }
 catch ( Exception )
 { }

以同步方式为您提供异步调用。