Static fields in an ASP.NET Webservice - asp.net

Is a static variable in a webservice shared between all running invocations of the webservice on a server?
In my case I want a server-wide sync-lock, and I beleive I can accomplish that with a single
private static Object syncHandle = new Object();
Is that correct?

Yes, they are all shared per AppDomain which is why, in general, they should not be used!
They should not be used, in general, because they are so unlikely to be used properly. Also because there are safer alternatives, like HttpContext.Cache, or even Session state.
Still, if you encapsulate all access to these static members, and if you handle locking correctly, then you'll have a safe implementation that may then turn out to be a bottleneck, with all threads contending for the shared resource. It's really better to do without.
Also, you seem to mean ASMX web services, but you should specify ASMX or WCF.

I believe they are shared as long as they are running in the same process. So two people requesting from the same server would have the same instance of the object. However, you can run different applications in a computer different process on IIS, in which case I'm pretty sure that instances to objects wouldn't be shared.

They are all shared unless you have a Web Garden. A web garden is multiple host process handling a single application. In this case each host will have its own static data.

Related

.net webservice and simultaneous access

I am trying to understand basic flow in a .net webservice.
Is the service instantiated again and again for different client connections? If I have a static class/members are they shared across? How is api concurrency maintained?
I guess my question is the application context/memory/address space shared across different requests (from say different users) or somehow the requests are sandboxed?
What you need to understand is instancecontextmode
Static memebers are shared within a process.
If instancecontext mode is not single then specify concurrency attribute.
Please refer this before proceeding.

How does ASP.NET webservices route requests do WebMethods?

I'm having problems because of a poorly written third-party library which our system heavily depends on. This library is not thread-safe (because of some bugs and static variables) and I need to use it in a ASP.NET webservice, which handles each user request in a separate thread.
I've tried many solutions for this problem. The best solution for now is, in my opinion, let subprocesses handle the requests. One subprocess will listen and handle the requests for one user, so I can synchronize access to the library code in a per user fashion, which is much better than all that I can do when sharing static variables between requests.
How can I route requests received by IPC communication to the appropriate WebMethods without reinventing the wheel? If possible, I would like to use the classes from .Net that handle this in a normal ASP.NET webservice, but I'm having a hard time trying to find their names.
TL;DR: I have a class MyWebService (that inherits from System.Web.Services.WebService) with some methods marked with WebMethodAttribute and I want to pass a made-up HttpRequest (or HttpContext) to it and tell it "handle it like you're receiving this from a real HTTP server, despite the fact the current process is a console application".
First, you may want to consider using WCF instead of ASMX, which is a legacy technology, kept only for backwards compatibility.
Second, you have another option: ensure that only a single thread ever uses the third-party libarary at a time. Placing lock blocks around all access to the third-party library may solve the problem.

WCF Optimal performance settings

Hi i am creating an API using WCF. My question can be broken down into two seperate ones
1) I have quite a few calls, for instance i have calls relating to the customer, products, orders, employees.
My question is should all this go into one public interface class e.g
public interface IRestService
public class RestService : IRestService
Or should I have one for each call e.g
public interface ICustomer
public class Customer : ICustomer
public interface IProducts
public class Products: IProducts
2) If you have an API which will be accessed by tens of thousands of users and thousands of users concurrently, how would you set up, what will your web config settings be for instance in terms of throttling. Also what setting would you give your InstanceContextMode, or ConcurrencyMode. Finally what type of binding would it be, bearing in mind websites and mobile phones can access the api.
For the sake of good practice, I would break up the API into separate interfaces so you have the option of splitting them into separate implementations in the future. You can still have just one service class implement all of the interfaces, like this:
public class RestService : ICustomer, IProducts, IOrders
However, it sounds as if you'd probably want to make them separate implementations anyway.
In terms of concurrency settings, ask yourself what resources need to be used on each call. If your service class's constructor can be written without any lengthy startup, then use PerCall. If you need to initialize expensive resources, then I'd recommend InstanceContextMode.Single with ConcurrencytMode.Multiple and make sure you write thread-safe code. Eg: make sure you lock() on any class properties or other shared resources before you use them.
Database connections would not count as "expensive to initialize", though, because ADO will do connection pooling for you and eliminate that overhead.
Your throttling settings will be revealed by testing, as Ladislav mentions. You'd want to stress-test your service and use the results to get an idea of how many machines you'd need to service your anticipated load. Then you'll need a dedicated load balancer to route requests as either round-robin, or something that checks the health of each server. Load balancers can be set up to GET a "systemhealth.asp" page and check the results. If you return an "OK" then that machine stays in the pool, or can be temporarily removed from the pool if it times out or returns any other status.
Your binding would need to be WebHTTPBinding for REST. BasicHTTPBinding is meant for SOAP interfaces and doesn't support [WebGet], for example.
If it doesn't have to be a REST service, then you can get a bit more performance by using NetTcpBinding.
If you really have few operations, single service can be used. Generally services are logical collection of related operations but the number of operations should be limited. Usually if your service have more than 20 operations you should think about refactoring.
Do you plan to use REST service? I guess you do because of your first interface example. In such case you need WebHttpBinding (or similar custom binding) with default InstanceContextMode (PerCall) and ConcurrencyMode (Single) values. Only other meaningful combination for REST service is InstanceContextMode.Single and ConcurrencyMode.Multiple but it will create your service as singleton which can have impact on your service implementation. My rule of thumb: Don't use singleton service unless you really need it.
Throttling configuration is dependend on your service implementation and on performance of your servers. What does thousands concurrent users really mean for you? Processing thousands of requests concurrently requires good server cluster with load balancer or hosting in Azure (cloud). All is also dependend on the speed of processing (operation implementation) and size of messages. The correct setting for MaxConcurrentInstances and MaxConcurrentCalls (should be same for PerCall instancing) should be revealed by performance testing. Default values for service throttling have changed in WCF 4.

ASP.NET Global/Static storage?

I have a thread-safe object which is part of an API previously used in windows service/client scenarios. This thread-safe object is essentially a singleton and stored in a static variable so that all callers can access the same state.
This API has recently started being used in an ASP.NET application, and I suspect that some funky behavior we're seeing may be due to unexpected AppDomain/lifecycle behavior. So I was wondering if I could get some verification:
Is a static variable reliably available for all requests, or does ASP.NET do any trickery with having multiple AppDomains for multiple requests?
I understand this would be the case for a web garden ... but our IIS is configured to use only 1 process, and is configured to only recycle once a day
Static variable should be the same for all requests in 1 worker process. I would suggest you to add logs to your asp.net application, especially in application_start/stop and in static constructor of a singleton to see what's happening.
Hope this helps.

ASP.NET A static object to hold connection with a DB. Is it a good idea?

I'm wondering if it is a good approach in the ASP.NET project if I set a field which "holds" a connection to a DB as a static field (Entity Framework)
public class DBConnector
{
public static AdServiceDB db;
....
}
That means it'll be only one object for entire application to communicate with a DB. I'm also wondering about if that object will be refreshing data changes from DB tables, or maybe it shouldn't be static and I shoud create a connection dyniamically. What do You think ?
With connection pooling in .NET, generally creating a new connection for each request is acceptable. I'd evaluate the performance of creating a new one each time, and if it isn't a bottleneck, then avoid using the static approach. I have tried it before, and while I haven't run into any issues, it doesn't seem to help much.
A singleton connection to a database that is used across multiple web page requests from multiple users presents a large risk of cross-contamination of personal information across users. It doesn't matter what the performance impact is, this is a huge security risk.
If you don't have users or personal information, perhaps this doesn't apply to your project right now, but always keep it in mind. Databases and the information they contain tend to evolve in the direction of more specifics and more details over time.
This is why you should not use a singleton design pattern with your database connection
Hope it helps
Is using a singleton for the connection a good idea in ASP.NET website
Bad idea. Besides the potential mistakes you could make by not closing connections properly and so forth, accessing a static object makes it very difficult to unit test your code. I'd suggest using a class that implements an interface, and then use dependency injection to get an instance of that class wherever you need it. If you determine that you want it to be a singleton, that can be determined in your DI bindings, not as a foundational point of your architecture.
I would say no.
A database connection should be created when needed to run a query and cleaned up after that query is done and the results are fetched.
If you use a single static instance to control all access to the DB, you may lose out on the automatic Connection Pooling that .NET provides (which could impact performance).
I think the recommendation is to "refresh often."
Since none of the answers have been marked as an answer and I don't believe any have really addressed question or issue thereof...
In ASP.NET, you have Global or HttpApplication. The way this works is that IIS will cache instances of your "application" (that is an instance of your Global class). Normally (default settings in IIS) you could have up to 10 instances of Global and IIS will pick any one of these instances in order to satisfy a request.
Further, keep in mind that, there could be multiple requests at any given moment in time. Which means multiple instances of your Global class will be used. These instances could be ones that were previously instantiated and cached or new instances (depending on the load your IIS server is seeing).
IIS also has a notion of App Pools and worker processes. A Worker process will host your application and all the instances of your Global classes (as discussed earlier). So this translates to an App Domain (in .NET terms).
Just to re-cap before moving on…
Multiple instances of your Global class will exist in the Worker process for your application (in IIS). Each one waiting to be called upon by IIS to satisfy a request. IIS will pick any one of these instances. They are effectively threads that have been cached by IIS and each thread has an instance of your Global class. When a request comes in, one of these threads is called upon to handle the request-response cycle. If multiple requests arrive simultaneously, then multiple threads (each contains an instance of your Global class) will be called upon to satisfy each of those requests.
Moving on…
Since there will be only one instance of a static class per App Domain you'll effectively have one instances of your class shared across all (up to 10) instances of Global. This is a bad idea because when multiple simultaneous requests hit your server they'll either be blocked (if your class’s methods use locks) or threads will be stepping on each other’s toes. In other words, this approach is not inherently thread-safe and if you make it thread safe using thread synchronization primitives then you’re unnecessarily blocking threads, negatively impacting performance and scalability of your web application, with no gain whatsoever.
The real solution (and I use this in all my ASP.NET apps) is to have an instance of your BLL or DAL (as the case may be) per instance of Global. This will ensure the following:
1. Multiple threads are not an issue since IIS guarantees one request-response per instance of Global) at any given moment in time. So you’re code is inherently threads-safe.
2. You only have up to 10 instances of your BLL/DAL up and running at any given moment in time ensuring that you're not constantly creating and disposing instances of (typically) large objects to satisfy each request, which on busy sites is huge
3. You get really good performance well due to #2 above.
You do have to ensure that your BLL/DAL is truly stateless or that you reset any state at the start of each Request-Response cycle. You can use the BeginRequest event in Global to do that is you need to.
If you go down this route, be sure to read my blog post on this
Instantiating Business Layers – ASP.NET

Resources