2012-10-15 47 views
1

在同步模式,它只是如何在使用语句中调用异步wcf方法?

using (MyServiceClient msc = new MyServiceClient()) 
{ 
    msc.Method(); 
} 

,但如果我必须等待这个方法的末尾,然后做一些事情,它不能正常工作

private void EventHandler<MethodCompletedEventArgs> myEventHandler = new EventHandler<MethodCompletedEventArgs>(methodBody); 

using (MyServiceClient msc = new MyServiceClient()) 
{ 
    msc.MethdCompleted += myEventHandler; 
    msc.BeginMethod(); 
} 

private void MethodBody() 
{ 
//exception: client state is aborted 
} 

而且如何调用异步mehod在using声明?

+0

哪种类型的应用程序正在调用该服务? –

+4

在您的事件处理程序中调用Dispose –

回答

1

您可以存储对服务客户端的引用,并在事件回拨后手动调用其方法Dispose。你只需要做一些额外的工作来管理异常,并且通常确保最终调用Dispose。另请注意您可能在等待旧版本完成时创建/覆盖msc的多个实例的情况:

确保在多次执行相同代码时不会丢弃错误实例的一种方法是使用本地拉姆达/匿名功能:

MyServiceClient msc = new MyServiceClient(); 

msc.MethdCompleted += (sender, args) => 
{ 
    try 
    { 
     myEventHandler(sender, args); 
    } 
    finally 
    { 
     msc.Dispose(); 
    } 
}; 

msc.BeginMethod(); 

它可能会比这更混乱;如果在msc.BeginMethod()上抛出异常,您应该很好地理解并且最有可能致电Dispose(但您不想多次拨打Dispose

+0

这还不够。 Dispose方法调用Close(),它通过网络进行呼叫以通知另一方拆除连接。如果连接处于Fault,Closing或Closed状态,则Close()调用将引发异常,并且资源不会被清理。如果发生这种情况,您需要调用Abort()。所以简单地使用try/finally或使用(){}是不安全的... – Craig

6

你不应该这样做。

您应该正常实例化MyServiceClient,然后在异步回调处理程序中将其Dispose

这是确保实例在调用回调处理程序后仍然存在的唯一方法,并且在回调处理程序完成其工作后它将被销毁。