我有一个ASP.NET应用程序,它使用第三方/异地支付处理器的“服务引用”。 我从支付处理器下载的示例代码包括以下内容:
public class SoapAPIUtilities{
private static CustomerProfileWS.Service service = null;
public static CustomerProfileWS.Service Service{
get{
if(service == null){
service = new CustomerProfileWS.Service();
}
return service;
}
}
}
我生成CustomerProfileWS.Service
automatically using Visual Web Developer:它的自动生成的实现是ServiceModel.ClientBase的子类的子类,
MSDN文档为“任何实例成员都不保证是线程安全的”。
要从ASP.NET页面使用此服务,我想我需要访问服务线程安全,以上不是?
如果它不是线程安全的,那么什么是使其成为线程安全的更好方法:
CustomerProfileWS.Service
实例,作为需要它们的ASP.NET页面的方法中的局部变量?答案 0 :(得分:1)
使代理线程安全且单例不适合Web应用程序。
当另一个线程正在使用它时,代理通道可能会出现故障。此外,您不希望为每个操作锁定通道,因为网站同时有多个请求,并且它们将在行中处理,等待长时间运行的任务,如调用Web服务。
您需要为每个ASP .NET请求创建一个新的代理通道。这是一项昂贵的操作,因此您可能希望查看本文以确保创建昂贵的部分得到缓存:
Performance Improvement for WCF Client Proxy Creation
另一种方法是创建一个代理池,这样您就不必每次都创建一个新代理,但如果可用,则重用现有代理。可以在这里找到一个例子:
答案 1 :(得分:0)
我会选择你建议的第二个选项......
不要使用静态单身人士;而是创建多个/临时 CustomerProfileWS.Service实例根据需要,作为局部变量 需要它们的ASP.NET页面的方法?
答案 2 :(得分:0)
我将其更改为private static readonly CustomerProfileWS.Service service = new CustomerProfileWS.Service();
。
这将以线程安全的方式创建您的单例。
但是,如果多个线程访问WCF代理,则可以关闭连接,而另一个是中间操作。
我认为每个ASP.NET请求的代理可能更适合这里。