2010-05-04 94 views
3

我处于Silverlight应用程序的中间,我有一个函数需要调用Web服务并使用结果完成函数的其余部分。Silverlight异步设计模式问题

我的问题是,我通常会做一个同步Web服务调用得到的结果,并使用该函数进行。由于Silverlight不支持没有其他自定义类来模拟它的同步Web服务调用,因此我认为最好使用异步流而不是与之对抗。所以我的问题涉及什么是在程序流程中处理异步调用的最佳设计模式。

在下面的示例中,我想根据Web服务调用的返回值使用myFunction TypeId参数。但是我不想调用Web服务,直到调用这个函数。我如何改变我的代码设计以允许异步调用?

 string _myPath; 

    bool myFunction(Guid TypeId) 
    { 
     WS_WebService1.WS_WebService1SoapClient proxy = new WS_WebService1.WS_WebService1SoapClient(); 
     proxy.GetPathByTypeIdCompleted += new System.EventHandler<WS_WebService1.GetPathByTypeIdCompleted>(proxy_GetPathByTypeIdCompleted); 
     proxy.GetPathByTypeIdAsync(TypeId); 

     // Get return value 

     if (myPath == "\\Server1") 
     { 
      //Use the TypeId parameter in here 
     } 
    } 

    void proxy_GetPathByTypeIdCompleted(object sender, WS_WebService1.GetPathByTypeIdCompletedEventArgs e) 
    { 
     string server = e.Result.Server; 
     myPath = '\\' + server; 
    } 

由于提前, 迈克

回答

2

鉴于Silverlight中的非同步性质不能从myFunction的返回值。相反,您可以传递一次服务调用完成后执行的Action。请参阅下面的示例代码。我不确定它是否被认为是最佳实践,但我使用这种“模式”很多,它对我一直工作得很好。

编辑
更新了下面的代码以在回调操作中包含多个参数。

void DoSomething(Guid TypeId, Action<int, bool> Callback) 
{ 
    WS_WebService1.WS_WebService1SoapClient proxy = new WS_WebService1.WS_WebService1SoapClient(); 
    proxy.GetPathByTypeIdCompleted += (s, e) => 
     { 
      string server = e.Result.Server; 
      myPath = '\\' + server; 

      // 
      if (myPath == "\\Server1") 
      { 
       Callback(888, true); 
      } 
      else 
      { 
       Callback(999, false); 
      } 
     }; 
    proxy.GetPathByTypeIdAsync(TypeId); 

} 

void CallDoSomething() 
{ 
    DoSomething(Guid.NewGuid(), (returnValue1, returnValue2) => 
     { 
      //Here you can do stuff with the returned value(s) 
     }); 
} 
+0

这个例子似乎很对我好,是有可能通过Action参数传递多个变量? 例如: CallBack(true,myObject); 谢谢。 – 2010-05-05 19:37:58

+0

当然,我只是更新了上面的示例代码,以包含int和bool作为参数。但是,您可以将其更改为任何您需要的。 – 2010-05-06 10:25:41

1

将GetPathByTypeId结果的处理放入GetPathByTypeIdCompleted回调中。在那里分配mypath。使mypath成为一个属性并实现INotifyPropertyChanged接口以通知Mypath的依赖者Mypath已更改。

  1. 观察员取决于mypath中
  2. 观察员通过GetPathByTypeId的异步调用
  3. mypath中设置设置的通知事件mypath中
  4. 获取mypath中,援引观察家的notifiaction
  5. 观察员可与mypath中
+0

我来到了相同的想法,我已经实现了这种方法。没关系,但它对我来说似乎并不高雅。但是,谢谢你的帮助。 – 2010-05-05 19:33:02

3

最好的办法是使用Reactive Extensions。然后(假设你在WS_WebService1SoapClient创建一个扩展方法IObservable<string> GetPathByTypeId(string typeId)你可以这样做:

proxy 
    .GetPathByTypeId(TypeId) 
    .Subscribe(server => 
     { 
      //Here you can do stuff with the returned value 
     }); 

由于紧邻有同步调用,因为它得到:)

+0

非常感谢,我会去看看 – 2010-05-05 19:31:04