I'm working on my Window Application and i'm using some static members.
public class MyParameter
{
public static string connectionString = "...";
}
Now if I install my application on computer and open two instance of same application. Will 'connectionString' common to the two instances?? Or every instance has its connectionString ?
The variable static or not is a part of your application memory. When you open 2 instances of your application you create two distinct memory locations in the OS, so there is not any relation between those 2 variables at all.
If you want to create one (relation), you have to look on different IPC (Inter Process Communication) methods available in OS, like:
Memory Mapped Files
Named Pipes
IPC Mechanisms in C# - Usage and Best Practices
No, Each application instance are isolated from one another using AppDomain. Thus each application instance will run in a seperate AppDomain and cannot access the variables from other domain. To do communicate with different domain we need to use Remoting , WCF Service
Every instance.
Static members are allocated on a per AppDomain basis. If you were to spawn a new AppDomain from within your current one.. they would be different.
Related
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?
I have a situation where a service is running a set of processes in the background. Those processes need to be started/stopped from a GUI application on demand. The issue is that the list of running processes is held in memory on an object that is designed to monitor and control them. This object is on the services instance and so not accessible from the GUI applications instance. What I think I need is to turn that object into a Singleton that is Globally static on the machine, like a Mutex, so that I can run it's methods from the GUI and have them affect the service. Example code is below, this is not the code I have but a much simplified version of it. I am interested in A solution to the Mutex based Singleton or an alternative that would suit my needs better.
namespace SystemWideSingleton
{
class Program
{
static void Main(string[] args)
{
while (true)
{
Console.Write("Count = " + GlobalSingleton.Instance.Count++);
Console.ReadLine();
}
}
}
public class GlobalSingleton
{
static GlobalSingleton() { }
private GlobalSingleton()
{
Count = 0;
}
private static readonly GlobalSingleton _instance = new GlobalSingleton();
public static GlobalSingleton Instance { get { return _instance; } }
public int Count { get; set; }
}
}
I would expect the above code to run as two console applications and for each application to share the output. ex.
Application 1: Application 2:
-------------- --------------
0 0
1 3
2 4
5 7
6 8
Any help would be very much appreciated.
P.S. I know that right now all I get out of the singleton is that it will work between threads on the same application instance. I need it to work across instances on the machine.
Putting whether it's a good idea aside and concentrating on the actual question, you could try using Memory mapped files, together with a mutex to prevent race conditions.
It would be somewhat cumbersome, but doable.
A number of options have been suggested to you. I would choose one of those. Please keep in mind that it is not easy to directly read memory of another process - it is OS and .NET CLR enforced security. You have to obey the rules and play right.
Perhaps the quickest way to do this is to use a global mutex (discussion on the best pattern to use it) backed up with a file, where you store a number of active instances. There can be many variations: you store this counter in the registry, a database, XML file, text file.
Or you can store a counter in a master (server) application and query/update it from slaves (clients) using RPC/WCF/SOAP/REST etc.
I think what you are going to find is that there is no "magic .NET" solution to this problem. Inter-process communication is something that needs to be designed based on what you are trying to accomplish.
To access methods that are running in other processes, you will need to expose those methods to inter-process communication channels. There are a variety of methods you can use to accomplish this, including WCF, depending on the degree of complexity that you require.
What is the easiest way to do inter process communication in C#?
Edit: If what you are trying to accomplish is (as you say it is) just to figure out "a list of running processes", System.Diagnostics.Process.GetProcesses() is probably the best way to do this. You can get process handles directly from the system, which is probably what you should be doing anyway. I don't understand the need for IPC or Mutexes or any of this other complicated stuff as an alternative.
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.
I have code to implement GoF's proxy pattern in C#. The code has MathProxy for calculating arithmetic functions.
The left side example is one implementation, and the right side is the better one for C# (.NET) with AppDomain.
What benefits can I expect using AppDomain especially with Proxy Pattern?
public MathProxy()
{
// Create Math instance in a different AppDomain
var ad = AppDomain.CreateDomain("MathDomain", null, null);
var o = ad.CreateInstance(
"DoFactory.GangOfFour.Proxy.NETOptimized",
"DoFactory.GangOfFour.Proxy.NETOptimized.Math");
_math = (Math)o.Unwrap();
}
Any given Windows process that hosts the CLR can have one or more application domains defined that contain the executable code, data, metadata structures, and
resources. In addition to the protection guarantees built in by the process, an application domain further introduces the following guarantees:
Faulty code within an application domain cannot adversely affect code running in a different application domain within the same process.
Code running within an application domain cannot directly access resources in a different application domain.
Code-specific configurations can be configured on a per application domain basis. For example, you can configure security-specific settings on a per application
domain basis.
AppDomain provides isolation boundary in CLR same as a process provides a isolation boundary at operating system level
Difference between AppDomain and Process :
Process:
When a user starts an application, memory and a whole host of resources are allocated for the application. The physical separation of this memory and resources is called a process. An application may launch more than one process. It's important to note that applications and processes are not the same thing at all.
AppDomain :
Microsoft also introduced an extra layer of abstraction/isolation called an AppDomain. The AppDomain is not a physical isolation, but rather a logic isolation within the process. Since more than one AppDomain can exist in a process, we get some benefits. For example, until we had an AppDomain, processes that needed to access each other's data had to use a proxy, which introduced extra code and overhead. By using an AppDomain, it is possible to launch several applications within the same process. The same sort of isolation that exists with processes is also available for AppDomains. Threads can execute across application domains without the overhead of inter process communication. This is all encapsulated within the AppDomain class. Any time a namespace is loaded in an application, it is loaded into an AppDomain. The AppDomain used will be the same as the calling code unless otherwise specified. An AppDomain may or may not contain threads, which is different to processes.
Why You Should Use AppDomains : Read Post
Good use case scenario for AppDomains :
"NUnit was written by .NET Framework experts. If you look at the NUnit source, you see that they knew how to dynamically create AppDomains and load assemblies into these domains. Why is a dynamic AppDomain important? What the dynamic AppDomain lets NUnit do is to leave NUnit open, while permitting you to compile, test, modify, recompile, and retest code without ever shutting down. You can do this because NUnit shadow copies your assemblies, loads them into a dynamic domain, and uses a file watcher to see if you change them. If you do change your assemblies, then NUnit dumps the dynamic AppDomain, recopies the files, creates a new AppDomain, and is ready to go again."
Entire info borrowed from Sacha Barbers article
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.