Are there any trouble on putting a web service's static method? - c#

I want that a method will be visible outside my application (web service) and inside it.
So, somethings like this:
[WebMethod]
public static CoordinataTratta TrovaTrattaPiuVicinaByCoordinate(double myLat, double myLng)
{
...
return coordinata;
}
// inside my application
var a = WebService.TrovaTrattaPiuVicinaByCoordinate(0, 0);
can create some problems?

Remember that each call to a web method will be processed in a separate thread in the same process. This means that all static variables will be shared between all threads and hence all calls to the web server. This may lead to hard to reproduce and debug problems.
Just making a method static is probably not a big problem but that can easily lead to using static variables/properties etc. This needs to be avoided in a web server.

It's not designed that way. The design is that an instance of the web service class will be created, and then an instance method will be called.
I can only guess why Microsoft designed it that way....
Read more...
https://stackoverflow.com/a/1263387/3156647

Related

Call static method with Azure WebJobs

I have created a dll which consist of static class.I referred them in my web-jobs(webjob1,webjob2,etc..) created and deployed in azure.
Each web-job may access a method simultaneously.As we are using static class, it will create single memory in heap. Every web-job contains the reference value of that static class. My Question is, will it create any problem?
As per my understanding, C# works in a synchronous fashion. Thus, each web-job will wait in a queue to access the functions of static class. So any change made for the variables of that static class will reflect on other webjobs.Since static class have stand alone memory.
If my assumption is right, why should we keep such static helper class instead of normal one which we can instantiate and use it.
I am creating static class like this inorder to get some details from my db.
public static class StaticHelper
{
public static string GetValue()
{
using(IDBContext _DbContext = new sampleDBContext())
{
}
//Acessing values through this context
}
}
If I understand it correctly, you have multiple webjobs that have the same dependency on a dll. You have multiple instances of that website and use use the SDK but not the queue trigger.
Each webjob will be running as its own process and each instance of the website may have other instances of those webjobs (depends on if you have set single instance or multiple instance).
"Each web-job may access a method simultaneously" - yes but they will be in different processes so you will be safe in that case.
If that answers your question, more detail is really in learning about how .net and multiple processes handle static logic (not really webjobs specific). I would start with Jeffry Richter to learn that detail.
Each WebJob runs in its own process, which is distinct from the WebApp's process (w3wp). So they will each have their own copy of static variables.
IS Azure Webjobs have its own memory allocation?

Problems with singleton pattern inside WCF service method

I will go ahead and preface this by saying: I am somewhat new to WCF.
I'm working on a server-side routine that's responsible for doing a great deal of business logic. It's accessible from a client via WCF.
My main WCF method calls off to several other private methods. Instead of passing around all of the "lookup data" I need for the business logic to each private method, I decided to use a singleton instance of a class named DataProvider that contains all of this "lookup data".
At the end of the routine, I "release" the DataProvider's lookup data so the next time the routine is executed, the latest lookup data will be used.
So, here's a simplified example:
public void Generate()
{
try
{
//populate singleton DataProvider with it's lookup data...
DataProvider.Instance.LoadLookupData();
//do business logic...
}
finally
{
//release provider's lookup data...
DataProvider.Release();
}
}
This works great until I have two different clients that execute the method at (or near) the same time. Problems occur because they share the same singleton instance and the task who finishes first will release the DataProvider before the other completes.
So...
What are my options here?
I'd like to avoid passing around all of the lookup data so the singleton pattern (or some derivative) seems like a good choice. I also need to be able to support multiple clients calling the method at the same time.
I believe the WCF service is configured as "Per-Call". I'm not sure if there's a way to configure a WCF service so that the static memory is not shared between service invocations.
Any help would be appreciated.
By default WCF is using "Per-Call", which means new instance of the WCF service is created for each client's call. Now since you implemented singleton even though new instance of the WCF is created it still calls your singleton.
If you would like to create lookup that is created for each call (like you have now) you should not do it as singleton. This way each client that calls your method will have new instance of the lookup, I think that was your intention.
However if you have lookup that is not changing that fast, I would recommend to share it between all calls, this will improve performance of your WCF service. You will need to declare your WCF service as
InstanceContextMode = InstanceContextMode.Single
ConcurrencyMode = ConcurrencyMode.Multiple
What this does is creating Singleton automatically for you by WCF, so you don't have to do it yourself, second it will support > 1 concurrent user (ConcurrencyMode.Multiple).
Now if you have your lookup that is changing and it needs to be reloaded after some period of time, I still would recommend using
InstanceContextMode = InstanceContextMode.Single
ConcurrencyMode = ConcurrencyMode.Multiple
but inside in your code cache it and then expire your cache at specific time or relative time (1 hours).
Here are some links that might help you:
3 ways to do WCF instance management (Per call, Per session and Single)
Hope this will help.
The static variables in a WCF service are always shared between instances regardless of the WCF InstanceContextMode setting. It seems you would be better off using a caching pattern for your look up data. The answers to this caching question provide some alternatives to rolling your own although they are a bit dated.
Also, if you decide that making the whole service instance a singleton (InstanceContextMode=Single) is the easiest solution be aware that you'll generally kill service scalability unless you also make your code multi-threaded (ConcurrencyMode=Multiple). If you can knock out thread-safe code in your sleep then a singleton service might be for you.
simplest is to use a synchronization mechanism - have you looked at lock(...) - this will act as a gatekeeper a lot like a critical section (if you have come across those in windows programming)
define a static object in your class
i.e.
static object lockObject = new object();
and use it in Generate method
i.e.
void Generate()
{
lock(lockObject)
{
...
}
}

Class Designing in C# - DAL

I came across a Data Access Layer Class that was made up entirely of static methods. This class was consumed by a Web Application
For e.g
public class DataAccessLayer
{
Public static PersonDetails GetDetails(int iPersonID);
{
//implementation
}
Public static bool SaveDetails(PersonDetails objPerson);
{
//implementation
}
}
Is it a good practice to write such code. I can understand the fact that the performance will be slightly better when I use static methods, but will this cause any concurrency errors when multiple users call the Page?
Is it a good practice to write such code.
Firing offense in my teams, breaks so many good practices I suggest whoever writes something like that goes to my competitors and works for them.
I can understand the fact that the performance will be slightly better when I use static methods.
Like 0.000000000000000000001%?
but will this cause any concurrency errors when multiple users call the Page?
Depends how the methods are written. It violates object orientation, though, makes dependency injection harder, makes it hard to use proper transactional demarcations under a transaction coordinator and makes it hard to unit test / mock things.
Static or not, you may get concurrency issues, it depends very much on how the actual code in your data access methods is written (e.g. use of transactions, are there fields used for concurrency checking in your data source etc.).
The static variable dies in a standalone application, because the
garbage collector cleans all your object because your application has
ended.
But if you are using this in a webapplication, your application is not
dead until your web server dies. So even if you closes the web browser,
your web server is not close. Try to shut down your server and your
variable will be no more.

Are static class instances unique to a request or a server in ASP.NET?

On an ASP.NET website, are static classes unique to each web request, or are they instantiated whenever needed and GCed whenever the GC decides to disposed of them?
The reason I ask is because I've written some static classes before in C# and the behavior is different than I would have expected. I would have expected static classes to be unique to each request, but it doesn't seem like that is the case.
If they are not unique to each request, is there a way to allow them to be?
UPDATE:
The answer driis gave me was exactly what I needed. I was already using a singleton class, however it was using a static instance and therefore was being shared between requests even if the users were different which in this case was a bad thing. Using HttpContext.Current.Items solves my problem perfectly. For anyone who stumbles upon this question in the future, here is my implementation, simplified and shortened so that it easy to understand the pattern:
using System.Collections;
using System.Web;
public class GloballyAccessibleClass
{
private GloballyAccessibleClass() { }
public static GloballyAccessibleClass Instance
{
get
{
IDictionary items = HttpContext.Current.Items;
if(!items.Contains("TheInstance"))
{
items["TheInstance"] = new GloballyAccessibleClass();
}
return items["TheInstance"] as GloballyAccessibleClass;
}
}
}
Your static classes and static instance fields are shared between all requests to the application, and has the same lifetime as the application domain. Therefore, you should be careful when using static instances, since you might have synchronization issues and the like. Also bear in mind, that static instances will not be GC'ed before the application pool is recycled, and therefore everything that is referenced by the static instance, will not be GC'ed. This can lead to memory usage problems.
If you need an instance with the same lifetime as a request, I would suggest to use the HttpContext.Current.Items collection. This is by design meant to be a place to store stuff that you need througout the request. For nicer design and readability, you can use the Singleton pattern to help you manage these items. Simply create a Singleton class that stores its instance in HttpContext.Current.Items. (In my common library for ASP.NET, I have a generic SingletonRequest class for this purpose).
Static members have a scope of the current worker process only, so it has nothing to do with requests, because different requests may or may not be handled by the same worker process.
In order to share data with a specific user and across requests, use HttpContext.Current.Session.
In order to share data within a specific request, use HttpContext.Current.Items.
In order to share data across the entire application, either write a mechanism for that, or configure IIS to work with a single process and write a singleton / use Application.
By the way, the default number of worker processes is 1, so this is why the web is full of people thinking that static members have a scope of the entire application.
Since the types are contained in an app domain, I would expect static classes to be present as long as the app domain is not recycled, or if the request gets served by a different app domain.
I can think of several ways to make objects specific to a particular request depends on what you want to do, for e.g. you could instantiate the object in Application.BeginRequest and then store it in HttpRequest object so that it can be accessed by all objects in the request processing pipeline.
If they are not unique to each request, is there a way to allow them to be?
Nope. Static members are owned by the ASP.NET process and shared by all users of the Web app. You'll need to turn to other session management techniques such as session variables.
Normally static methods, properties and classes are common at the Application level. As long as the application lives, they are shared.
You can specify a different behaviour by using the ThreadStatic attribute. In that case they will be specific to the current thread, which, I think, is specific for each request.
I would not advise this though as it seems overcomplicated.
You can use HttpContext.Current.Items to set stuff up for one request, or HttpContext.Current.Session to set stuff up for one user (across requests).
In general though, unless you have to use things like Server.Transfer, the best way is basically creating things once and then passing them explicitly via method invocation.

Web service variable shared for the lifetime of the webservice?

How can I make a variable (object) available for the whole lifetime of the webservice?
Static variable seem to work but is there an other way to do it?
Static variables exist for the lifetime of the App Domain that contains them. In the case of a web service, this is usually the ASP.Net Worker Process. What that means is that when IIS decides to cycle the worker process, your static variable will be gone. This may be what you want, in which case it is probably a good choice. (Putting asside discussions of whether or not static variables are proper in a given context).
Within the scope of a web service you also have access to the HttpApplicationState via the Application property (this would be an asmx service...not sure if WCF is the same or not), so this could also be a good choice for stashing something needed for the lifetime of a service.
A singleton utilizing HttpApplicationState should work a treat
probably, but if static variable works then move on to the next problem ! :)

Categories

Resources