Call static method with Azure WebJobs - c#

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?

Related

Is it safe to use a C# static class as a means of sharing data from one azure function to another?

I have two functions under a Azure function plan. Also included in there is a static class with a public static string. Can I use this static string as a means of transferring data from one function to the other?
The main concern I have is regarding instances. If each trigger creates a new copy of the static class and its string content then I believe this shouldn't be a problem. So does each trigger of the first function that calls the static class create a new copy for itself of it or is it shared among different simultaneous function clients?
Should I look for an alternative approach like Redis cache or something similar?
Azure function is serverless. If you are running under a consumption plan multiple function instance will start executing and when instance is idle, it will release instances.
Maintaining state outside function is best approach.
I used Redis for same and seen lot of performance improvement in my application. If you have frequent read/write Redis is best option and you have to pay a dedicated amount for Redis instance.
If function request is not very frequent or budge is constant, you can use "Azure Storage Table" as well. you don't need to pay a dedicated amount.
Azure Functions offers an alternative for creating stateful functions called Durable Functions. Durable Functions is an extension to the Azure Functions runtime that enables the definition of stateful workflows in code.
For more information follow the below docs.
https://learn.microsoft.com/en-us/dotnet/standard/serverless-architecture/durable-azure-functions
https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview
The best way to achieve what you are trying to do is to use queues with payloads.
Basically one functions puts the data you want to transfer in a queue. The other function has a Queuetrigger that once a message shows will run (being able to access the data)

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

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

Is a static object the same object in multiple running applications?

If you have a windows service and a windows forms application that uses the same static object, is it the same object in both applications? In other words if I update the object in the service will it also be updated in the forms application as well if both are running at the same time?
They run on different processes so they don't share the static object.
Not exaclty related with your question but threads created on the same application is a different story. They will share the static variable unless is marked with ThreadStatic attribute
No. Unless you do something specific to achieve this objects are not shared between different processes.
The simple answer to this is is that each process has its own static so no, it will not be shared between the service and desktop process.
The complicated part is that there may even be multiple instances of a static in a single process.
In Java there is one instance of the static object for each ClassLoader that loads the class. I checked for equivalent functionality in C#. I found this question on SO that suggests that there is indeed something similar to multiple classloaders in in C# (I guess actually in CLR) and though I did not find any specific reference to multiple instances of a static I am sure that would be the case.
Simply put no,
static is 'static per AppDomain' (and you could have multiple domains per process), so not even for one process is safe to assume that your static variables will be 'shared' (normally is true unless you create new domains by hand, e.g. see What is AppDomain?) - e.g. web apps typically break the 'static' singletons etc.
In other words you need to use some sort of persistence to be able to share your data in between different applications. Or use remoting, WCF to communicate over application (domain) boundaries.
I think each application runs in its own Process. I really doubt that updating a static object in Windows service have any effect on static object running as Windows forms application.
Windows service runs under system account where as a Windows forms application runs under User account.
As others have pointed out in the comments, the processes run in different memory. Each process has
its own address space.
Windows service responds to Service control Manager commands.
They are completely two different things.

Can a static class be instantiated more than once within a single process?

Can a single process with multiple threads cause a static class to be created more than once?
If I just need a simple construct can I use a static class, or do I have to resort to a singleton?
Yes a static class can act as a singleton-like construct. All the static members it contains will only exists once - but per AppDomain (just keep in mind that one process can have multiple (isolated) .NET AppDomains).
Can a single process with multiple
threads cause a static class to be
created more than once?
No, multiple threads will all point to the same static class.
If I just need a simple construct can
I use a static class, or do I have to
resort to a singleton?
Don't really understand your question. But general you use Singleton when you need to have global data access. You can get the same thing with static class with static members. But that makes the code uglier because there are just too many statics keywords and makes your life difficult should you want to discard the global access strategy and use a more OOP approach.
Singleton, however, is a much preferred method, compared to static class.
Edit: You may want to read this: static classes are not thread-safe
I think when you say "created" you really mean "instantiated," instantiation being the creation of an object of that class. Static classes are never instantiated. They are essentially a collection of global variables and functions.
One instance of each static member variable is created at runtime, and they will be shared among all threads.
Can a single process with multiple
threads cause a static class to be
created more than once?
Irrespective of the number of threads, the only way to get more than one instance of static .NET class (members) in a process is by making new AppDomains. Each AppDomain will then have one instance of the static class (members).
AppDomain Class # MSDN
edit:
I should add that the number of threads in a process and the number of AppDomains are separate as well. A single-threaded process create any number of AppDomains if it wished. Also, it is only up to program flow whether any extra threads call into additional AppDomains. This could create a situation where multiple threads are accessing more than one instance of a static class, but it won't happen unless you explicitly create this scenario yourself.
If I just need a simple construct can
I use a static class, or do I have to
resort to a singleton?
It seems unclear what you're trying to ask here. Static class members represent singletons by concept. If you're asking whether this is a good method of creating a simple construct, the answer is maybe. It depends on what your needs are. Most will argue that you should just use a regular class definition and just make one instance.
Given your two questions in conjunction, I would speculate that maybe you are asking if you can create only one instance as a singleton by using a static class. The answer is yes, as you won't automatically have new AppDomains unless your code explicitly creates one or if you import code that creates new AppDomains using your assemblies.
You can't create an instance of a static class...
But a static instance of a normal class will be the same over all threads
Can a single process with multiple threads cause a static class to be created more than once?
Yes you can, though it's somewhat unusual to do (or even want to). It requires either a separate AppDomain, or use of ThreadStaticAttribute. Either of those will give you a separate instance that does not share state with other static instances.
If I just need a simple construct can I use a static class, or do I have to resort to a singleton?
You can use either. A singleton allows you to use a non-static class like a static, and gives you some additional flexibility in managing lifetime.

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.

Categories

Resources