我想知道如何安全地调用WCF Web服务方法。这两种方法都可接受/等同吗?还有更好的方法吗?
第一种方式:public Thing GetThing()
{
using (var client = new WebServicesClient())
{
var thing = client.GetThing();
return thing;
}
}
第二种方式:
public Thing GetThing()
{
WebServicesClient client = null;
try
{
client = new WebServicesClient();
var thing = client.GetThing();
return thing;
}
finally
{
if (client != null)
{
client.Close();
}
}
}
我想确保客户端已正确关闭并处理掉。
由于
答案 0 :(得分:4)
使用using
(没有双关语)是not recommended,因为即使Dispose()
也会抛出异常。
以下是我们使用的几种扩展方法:
using System;
using System.ServiceModel;
public static class CommunicationObjectExtensions
{
public static void SafeClose(this ICommunicationObject communicationObject)
{
if(communicationObject.State != CommunicationState.Opened)
return;
try
{
communicationObject.Close();
}
catch(CommunicationException ex)
{
communicationObject.Abort();
}
catch(TimeoutException ex)
{
communicationObject.Abort();
}
catch(Exception ex)
{
communicationObject.Abort();
throw;
}
}
public static TResult SafeExecute<TServiceClient, TResult>(this TServiceClient communicationObject,
Func<TServiceClient, TResult> serviceAction)
where TServiceClient : ICommunicationObject
{
try
{
var result = serviceAction.Invoke(communicationObject);
return result;
} // try
finally
{
communicationObject.SafeClose();
} // finally
}
}
这两个:
var client = new WebServicesClient();
return client.SafeExecute(c => c.GetThing());
答案 1 :(得分:1)
第二种方式稍微好一些,因为你正在应对可能引发异常的事实。如果你陷入困境并且至少记录了特定的异常,那就更好了。
但是,此代码将阻止,直到GetThing
返回。如果这是一个快速操作,那么它可能不是一个问题,但另一种更好的方法是创建一个异步方法来获取数据。这会引发一个事件以指示完成,并且您订阅该事件以更新UI(或者您需要做什么)。
答案 2 :(得分:0)
不完全: