如果您从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”,这样做的最佳方式是什么?
谢谢, 杰夫
答案 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 )
{ }
以同步方式为您提供异步调用。