问题
I have an ASP.NET application, which uses a 'service reference' to a 3rd-party/offsite payment processor. The sample code which I downloaded from the payment processor includes the following:
public class SoapAPIUtilities{
private static CustomerProfileWS.Service service = null;
public static CustomerProfileWS.Service Service{
get{
if(service == null){
service = new CustomerProfileWS.Service();
}
return service;
}
}
}
I generate CustomerProfileWS.Service
automatically using Visual Web Developer: its auto-generated implementation is a subclass of subclass of ServiceModel.ClientBase, which
MSDN documents as, "Any instance members are not guaranteed to be thread safe".
To use this service from ASP.NET pages, I guess I need to make access to the service thread-safe, which the above is not?
- The answers to this question say that it is thread-safe
- But the end of this MSDN page says that it is not thread-safe?
If it is not thread-safe then what is the better way to make it thread-safe:
- Wrap an accessor class which implements a lock around the static singleton (e.g. as shown here)?
- Don't use a static singleton; instead create multiple/temporary
CustomerProfileWS.Service
instances as needed, as local variables in methods of the ASP.NET pages which need them?
回答1:
Making a proxy thread safe and singleton is not suitable for web applications.
The proxy channel could become faulted while another thread is using it. Also, you don't want to lock the channel for every operation because a website has many requests at the same time and they will be processed in row, waiting for a long running task, like calling a webservice.
You need to create one new proxy channel for each ASP .NET request. This is an expensive operation, so you might want to look at this article to make sure that the parts that are expensive to create are cached:
Performance Improvement for WCF Client Proxy Creation
Another way is to create a Pool of proxies, so that you don't have to create a new proxy each time, but reuse an existing one if it is available. An example can be found here:
A Sample for WCF Client Proxy Pooling
回答2:
I would go with the 2nd option you suggest...
Don't use a static singleton; instead create multiple/temporary CustomerProfileWS.Service instances as needed, as local variables in methods of the ASP.NET pages which need them?
回答3:
I'd change it to private static readonly CustomerProfileWS.Service service = new CustomerProfileWS.Service();
.
This will create your singleton in a thread safe way.
However, if multiple threads access the WCF proxy, one could close the connection while the other is mid operation.
I think a proxy per ASP.NET request might be better suited here.
来源:https://stackoverflow.com/questions/21047666/thread-safe-access-to-wcf-channel