Monitor.TryEnter with Generic Class - c#

I have a situation where, for testing, I only want my timer method (FooMethod) to run one at a time. In the example below, FooMethod is passed as the delegate to a timer. There are many concrete instances of this class. I thought that by making _locker static, only one instance of FooMethod() would process at a time. But when I run the app, multiple threads are getting past the TryEnter() line at a time.
This is how I'm adding each class to a new timer. This is done, in a loop, for each foo instance:
_timers.Add(new Timer(foo.FooMethod, null, 0, 10000));
And this is the class that has that method:
public class Foo<T>
{
private static readonly object _locker = new object();
public void FooMethod(object stateInfo)
{
// Don't let threads back up; just get out
if (!Monitor.TryEnter(_locker)) { return; }
try
{
// Logic here
}
finally
{
Monitor.Exit(_locker);
}
}
}
Note: Normally, _locker isn't static; I don't want the same thread entering the method before it got a chance to complete. I changed it to static here for testing.
My first thought is that maybe this isn't working because the class is generic? And that each concrete class is actually its own class and they don't share the _locker variable? Is that true? If that's true how should I have the concrete classes share a _locker variable? Do I need to add a static _locker variable to some other class to which the Foos have access?

Do I need to add a static _locker variable to some other class to
which the Foos have access?
Yes.
Each closed Foo<T> type, with different T arguments, has its own static _locker object. You could make Foo inherit from a base class, and put the static object there. Then, all the types would use the same instance.

Maybe
public class Foo
{
protected static readonly object _locker = new object();
}
public class Foo<T> : Foo
{
public void FooMethod(object stateInfo)
{
if (!Monitor.TryEnter(_locker)) { return; }
try
{
// Logic here
}
finally
{
Monitor.Exit(_locker);
}
}
}

You are correct. Each unique type T referenced in code causes the CLR to generate a new concrete type for Foo<T> and each has its own set of static members.
You could restructure your code to look like the following. It is but one among many valid variations.
public class Foo
{
private static readonly object _locker = new object();
public void FooMethod(object stateInfo)
{
// Don't let threads back up; just get out
if (!Monitor.TryEnter(_locker)) { return; }
try
{
// Logic here
}
finally
{
Monitor.Exit(_locker);
}
}
}
public class Foo<T>
{
public void FooMethod(object stateInfo)
{
Foo.FooMethod(stateInfo);
}
}
Also, keep in mind that you can start the timer with an infinite period to prevent the callback from executing more than once. Call Change again at the end of FooMethod to queue the timer again. Since you have multiple timers all going at once you will still have multiple concurrent executions of FooMethod going simultaneously, but at least now there will only be one active call per timer. That is not exactly what you asked for, but I thought I would point this out anyway.
_timers.Add(new Timer(foo.FooMethod, _timers.Count, 10000, Timeout.Infinite));
public class Foo<T>
{
public void FooMethod(object stateInfo)
{
try
{
// Logic here
}
finally
{
int index = (int)stateInfo;
_timers[index].Change(10000, Timeout.Infinite);
}
}
}

Please make this class as non-generic type. That would purpose your need.
public class Foo
{
private static readonly object _locker = new object();
public void FooMethod(object stateInfo)
{
// Don't let threads back up; just get out
if (!Monitor.TryEnter(_locker)) { return; }
try
{
// Logic here
}
finally
{
Monitor.Exit(_locker);
}
}
}

Related

Static property is null after being assigned

I have this code:
static class Global
{
public static readonly IChannelsData Channels = new ChannelsData();
public static readonly IMessagesData Messages = new MessagesData();
}
My understanding is that, because this class is static, it is impossible for Global.Channels or Global.Messages to be null now that they have been given an instance.
However, I try to access the property with
public class Channel : IComparable
{
...
private SortedList<string, Message> _messages;
[JsonConstructor]
public Channel()
{
_messages = new SortedList<string, Message>();
}
[OnDeserialized]
private void Init(StreamingContext context)
{
**Global.Channels.RegisterChannel(this);**
}
...
}
I get a NullReferenceException on Global.Channels, which I have confirmed in the immediate window. Further confusing me, I can hit the breakpoint at new ChannelData(), so I know the static member is being populated - successfully - at some point.
More context, comment request:
private Hashtable _channels;
public ChannelsData()
{
_channels = new Hashtable();
foreach(Channel channel in SlackApi.ChannelList())
{
_channels.Add(channel.GetHashCode(), channel);
}
}
It feels like something similar to the problem here. However, in my situation I'm deserializing using JSON.NET and not WCF and the property in question is in a separate static class, not in the same class. I also can't use the workaround of a solution posted there.
Full stack trace:
at Vert.Slack.Channel.Init(StreamingContext context) in C:\\Vert\Slack\Channel.cs:line 48
And error:
Object reference not set to an instance of an object.
I've been able to reproduce it with the following:
class Program
{
static void Main(string[] args)
{
var m = Global.Messages;
}
}
[Serializable]
public class Blah
{
[OnDeserialized]
public void DoSomething(StreamingContext context)
{
Global.Channels.DoIt(this);
}
}
static class Global
{
private static Blah _b = Deserialize();
public static readonly IChannelsData Channels = new ChannelsData();
public static readonly IMessagesData Messages = new MessagesData();
public static Blah Deserialize()
{
var b = new Blah();
b.DoSomething(default(StreamingContext));
return b;
}
}
Essentially, the order of execution is:
var m = Global.Messages; causes the static initializer to run for Global.
According to ECMA-334 regarding static field initialization:
The static field variable initializers of a class declaration
correspond to a sequence of assignments that are executed in the
textual order in which they appear in the class declaration. If a
static constructor (ยง17.11) exists in the class, execution of the
static field initializers occurs immediately prior to executing that
static constructor. Otherwise, the static field initializers are
executed at an implementation-dependent time prior to the first use of
a static field of that class
This is the root cause. See the comments for more context on the circular reference
This essentially means that we're calling Deserialize and hitting Global.Channels.DoIt(this); before the initializer has a chance to finish setting up. As far as I'm aware, this is the only way a static field cannot be initialized before being used - after some testing, they are indeed created even when using run-time dispatches (dynamic), reflection and GetUninitializedObject (for the latter, initialization is done on the first method call, however)..
Though your code may be less obvious to diagnose (for example, if the chain is kicked off by another static class referencing). For example, this will cause the same issue but is not as immediately clear:
class Program
{
static void Main(string[] args)
{
var t = Global.Channels;
}
}
[Serializable]
public class Blah
{
[OnDeserialized]
public void DoSomething(StreamingContext context)
{
Global.Channels.DoIt();
}
}
public interface IChannelsData { void DoIt(); }
class ChannelsData : IChannelsData
{
public static Blah _b = Deserialize();
public static Blah Deserialize()
{
var b = new Blah();
b.DoSomething(default(StreamingContext));
return b;
}
public void DoIt()
{
Console.WriteLine("Done it");
}
}
static class Global
{
public static readonly IChannelsData Channels = new ChannelsData();
public static readonly IMessagesData Messages = new MessagesData();
}
So:
If you have anything else in Globals before those fields, you should investigate them (if they were left out for brevity). It may be simple as moving the Channels declaration to the top of the class.
Inspect ChannelsData for any static references, and follow those to the source.
Setting a breakpoint in DoSomething should give you a stack trace back to the static initializers. If it doesn't, try to replicate the issue by invoking new Blah(default(StreamingContext)) where it would usually be deserialised.

Risk by using a static property in a multi-threading (or web) c# project

i am a little confused by multi-thread access risk on a static property in C#.
public class MyClass
{
public static MyClass Static
{
get
{
var c = new MyClass();
c.SomeProperty = "12345";
c.OtherProperty = DateTime.Now.ToString();
return c;
}
}
}
This example class provides a static property that create a new instance of MyClass,
like a method:
public class MyClass
{
public static MyClass Static()
{
var c = new MyClass();
c.SomeProperty = "12345";
c.OtherProperty = DateTime.Now.ToString();
return c;
}
}
Obviously, this property is not a "storage" box for an instance of MyClass, but it behaves like a static method (that, if i reading good a msdn article, is completely thread-safe).
My question is: i risk something with using this concept ?
Especially in a web or multi-thread enviroinment ?
There is a no particular utility in using it, only for simple reading and cleaning code:
MyClass.Static.SomeProperty = "Something";
is more clear than
MyClass.Static().SomeProperty = "Something";
All help will be appreciated
Thanks
In both your examples you're returning a new instance of MyClass every time the property is accessed. There is no danger that you'll have any concurrency issues when multiple threads access the static property method at the same time, because they're actually modifying the properties of their own instance of MyClass and not sharing it between them.
If you had something like this instead:
public class MyClass
{
private static MyClass _myClass;
public static MyClass Static
{
get
{
return _myClass ?? (_myClass = new MyClass());
}
}
}
...then you'd cause problems when two threads attempted to write/read properties of the resulting MyClass instance, because they're operating on the same MyClass reference _myClass.
Even so, there are two issues with the code you've posted:
You need to change it to a method and rename it, because it's actually creating something, not accessing a static version of anything. Then you can operate on the return value. Something like this:
public class MyClass
{
public static MyClass Create()
{
var c = new MyClass();
c.SomeProperty = "12345";
c.OtherProperty = DateTime.Now.ToString();
return c;
}
}
Then use it like this:
var myClass = MyClass.Create();
myClass.SomeProperty = "Stuff";
The way you're setting properties currently means their values aren't persisted, because a new MyClass is created the next time the Static property is accessed.
If when you set SomeProperty you actually want a static instance to be updated you'll need to lock on a static object to solve the multi threading issue - something like this:
public static class MyClass
{
private static readonly object locker = new object();
private static string someProperty;
public void SetSomeProperty(string val)
{
lock (locker)
{
someProperty = val;
}
}
public void GetSomeProperty()
{
lock (locker)
{
return someProperty;
}
}
}
It seems that you are creating a static factory method that will give you a fully instantiated object.
Threading would not be an issue here because every time you call this method or property you are creating a new object. If 2 threads call the same method at the same time they will each keep on working on the object they are dealing with
Having said that - Perhaps you should reexamine how you are using the class - because if you call this in your code
MyClass.Static.SomeProperty = "Something";
You are basically throwing away the object after it has been instantiated
you would need to assign it to a variable and store it. - the next time you call that function you will receive a new object.
Perhaps I was not able to explain properly, my question was referred multithreaded access on static properties.
I can confirm that they are thread-safe, if the returned object is bound to the current thread.
Here is the example of what I implemented:
public interface IObjectFactory
{
T CreateOrReuse<T>() where T : class, new();
T CreateOrReuse<T>(string key) where T : class, new();
T CreateOrReuse<T>(string key, params object[] args) where T : class;
}
public class ThreadObjectFactory : IObjectFactory
{
// implementation to create and store into the Thread Data
}
public class HttpSessionObjectFactory : IObjectFactory
{
// implementation to create and store into the current session
}
Now the singleton:
public class MyClass
{
public int PageLoadCounter = 0;
public static MyClass Static
{
get
{
IObjectFactory factory = new HttpSessionObjectFactory();
return factory.CreateOrReuse<MyClass>();
}
}
}
And this is the final use:
public class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
MyClass.Static.PageLoadCounter++;
}
}
Thanks for the replies, even if the question was not very clear

How to initialize an object from one method to another method within a class?

In a class, I have 2 methods. In method1 I created an object, but I can't use the same object in method2.
Why? Please help with a simple example.
The coding is too big, so I have given the layout
public class Sub
{
}
public class DataLoader
{
public void process1()
{
Sub obj = new Sub();
}
public void process2()
{
// here I can't use the object
}
}
The reason why this isn't working is scope. A local variable can only be accessed from the block it is declared in. To access it from multiple methods, add a field or pass it to the other method as a parameter.
Field:
class YourClass
{
object yourObject;
void Method1()
{
yourObject = new object();
}
void Method2()
{
int x = yourObject.GetHashCode();
}
}
Parameter:
class YourClass
{
void Method1()
{
Method2(new object());
}
void Method2(object theObject)
{
int x = theObject.GetHashCode();
}
}
You should use member variables in your class.
public class DataLoader
{
private Sub mySub;
public void Process1()
{
mySub = new Sub();
}
public void Process2()
{
if(mySub == null)
throw new InvalidOperationException("Called Process2 before Process1!");
// use mySub here
}
}
Read up on different variable scopes (specifically, instance variables in this case). You can also pass your object as a parameter, like codesparkle mentioned in their answer.
The short answer (without seeing your code) is that the object created in Method1 doesn't have any visibility, or scope, in Method2.
There are already some good answers here that show you how to solve your specific problem. But the real answer here is to familiarize yourself generally with the concept of Scope. It's a fundamental part of programming and learning more about it will help you tons.
There are many good articles and videos on the subject. This video is a great start. Good luck!
You have to set the object as a class field, then you can access it from every method of your class.

How to overload a method at run-time or other ideas in C#

Maybe overloading a method is not exactly what is necessary but this is the best i could come up with.
I have a class:
public class Worker {
private string jobType;
public Worker(string jt)
{
this.jobType = jt;
}
public void ProcessJob()
{
if(jobType.Equals("Pizza") MakePizza();
else if (jobType.Equals("Burger") MakeBurger();
}
private void MakePizza()
{
// make pizza
}
private void MakeBurger()
{
// make burger
}
}
The above is just an example of illustration. When the class is constructed, it is constructed with a specific job type, and that won't change. However it may need to perform millions of jobs, always of the same type. The ProcessJob() will be called all the time, but the caller won't know what type of worker this is. I would like to avoid running the if check every single time, there has to be a way to do that check only once and prep it.
In my case, making child classes (pizza worker, burger worker, etc.) is not an option, as in my real case, the class is large and there is only one tiny difference. Changing it will impact the whole architecture so it needs to be avoided.
Create an abstract base class, which contains common things a worker can do. Then declare derived classes for specialized workers.
public abstract class Worker
{
public abstract void ProcessJob();
}
public class PizzaWorker : Worker
{
public override void ProcessJob()
{
// Make pizza
}
}
public class BurgerWorker : Worker
{
public override void ProcessJob()
{
// Make burger
}
}
Now you can create workers of different types and let them do their job:
var workers = new List<Worker>();
workers.Add(new PizzaWorker());
workers.Add(new BurgerWorker());
foreach (Worker worker in workers) {
woker.ProcessJob();
}
This will automatically call the right implementation of ProcessJob for each type of worker.
Note: If-else-if cascades and switch statements are often an indication that the code works in a procedural rather than object-oriented way. Refactor it to be object-oriented!
You could use a delegate created when the object is constructed, this way the dispatch is done automatically:
public class Worker
{
private delegate void MakeSomething();
private MakeSomething makeWhat;
private string jobType;
public Worker(string jt)
{
this.jobType = jt;
switch (jt)
{
case "Pizza":
makeWhat = new MakeSomething(MakePizza);
break;
case "Burger":
makeWhat = new MakeSomething(MakeBurger);
break;
default:
throw new ArgumentException();
}
}
public void ProcessJob()
{
makeWhat();
}
private void MakePizza()
{
//make pizza
}
private void MakeBurger()
{
//make burger
}
}
I would still recommend to use sub classes. If you cannot inherit from Worker then create new class hierarchy that is used inside the worker. This way anyone using Worker class doesn't have to know that there are sub classes. If you really really hate sub classes or you have some other reason you don't want them you can use dictionary. It contains job type as key and Action as the method it calls. If you need more jobs just create the private method and register it in the RegisterWorkers method.
private Dictionary<string, Action> actions = new Dictionary<string, Action>();
public Worker(string jt)
{
this.jobType = jt;
this.RegisterWorkers();
}
private void RegisterWorkers
{
this.actions["Pizza"] = this.MakePizza;
this.actions["Burger"] = this.MakeBurger;
}
public void ProcessJob()
{
var action = this.actions[this.jobType];
action();
}
No, I don't think it should be avoided. Any common functionality should go in a base class. I think you need a static factory method, that returns a child class based on the string parameter.
public abstract class Worker {
public virtual void ProcessJob();
public static Worker GetWorker(string jobType) {
if(jobType.Equals("Pizza")
return new PizzaWorker();
else if (jobType.Equals("Burger")
return new BurgerWorker();
else
throw new ArgumentException();
}
// Other common functionality
protected int getFoo() {
return 42;
}
}
public class PizzaWorker : Worker {
public override void ProcessJob() {
// Make pizza
int y = getFoo() / 2;
}
}
public class BurgerWorker : Worker {
public override void ProcessJob() {
// Make burger
int x = getFoo();
}
}
So to use this:
Worker w = Worker.GetWorker("Pizza");
w.ProcessJob(); // A pizza is made.
This is exactly why there are patterns: Command, Strategy, Decorator.
I believe the command pattern is what you are looking for. First you have a basic 'command' template:
public interface IJob {
void ProcessJob();
}
Different jobs would then be performed as follows:
public class MakePizza : IJob {
// implement the interface
public void ProcessJob() {
// make a pizza
}
}
Now, you could have a JobFactory as follows:
public static class JobFactory {
public static IJob GetJob(string jobType) {
if(jobType.Equals("Pizza"){
return new MakePizza();
} else (jobType.Equals("Burger") {
return new MakeBurger();
}
// to add jobs, extend this if-else-if or convert to switch-case
}
}
Worker can now look like this:
public class Worker {
private IJob job;
public Worker(string jt) {
job = JobFactory.GetJob(jt);
}
public void ProcessJob() {
job.ProcessJob();
}
}
If you don't have access to code to make these changes, then another pattern you may want to look into is the Adapter.
You're talking about basic inheritance here. There are a couple of ways that you could do this.
Make a Base Class that is
public class Job
{
virtual void ProcessJob();
}
Then a MakePizza class
public class MakePizza : Job
{
public void ProcessJob()
{
//make Pizza
}
}
Then in your worker class instead of having a JobType as a string which will lead to all kinds of potential bugs.
public class Worker{
private Job jobType;
public Worker(Job jt){
this.jobType = jt;
}
public void ProcessJob()
{
Job.ProcessJob();
}
}
If you have to pass through a string you could simply load up the JobType through reflection, throwing a error if the type doesn't exist.
having to change other classes means you need to change code, not that you need to change architecture. the best answer is just to change the code. in the long term, the maintenance burden of having to write this in a less-than-ideal fashion will cost you more than just changing the code. use inheritance and bite the bullet on making the change now. if you have iterators that will have problems with dealing with subtypes, your iterators are doing more than being iterators, and you are better off fixing that than going forward with them. if the other classes care about what subtype of worker they are dealing with, that's a problem in and of itself that you should fix. ultimately, the dependent code should not care which type of worker it is. that's really what you are after anyway. the instance of a type that has work as its base type is still a worker and that is all the class using a worker should care about.

Locking the Static object inside the static property in the HTTPModule

We have a custom DLL implemented IHttpModule to handle the httpApplication_EndRequest, what I want to know is
The DLL has a class (not a static class) which has a static property is used to create an instance for a static variables/object reference defined inside the class.
Now, should I need to lock inside static property before creating an instance for the static object/variable?
Eg:-
public class SPEnvironment : IEnvironment
{
private static SPEnvironment _instance;
private static object _syncRoot = new object();
private SPEnvironment()
{
try {
.....
}
finally {
......
}
}
public static SPEnvironment Instance
{
get
{
if (_instance == null)
{
lock (_syncRoot)
{
if (_instance == null)
{
_instance = new SPEnvironment();
}
}
}
return _instance;
}
}
}
I will calling this from an another class, like below
SPEnvironment.Instance;
Is it the right way? or the lock should be removed?
The double null check with a lock in the middle is a good, thread-safe way of instantiating a singleton. However, you could save yourself a lot of code by just saying
public class SPEnvironment : IEnvironment
{
public static SPEnvironment Instance = new SPEnvironment();
private SPEnvironment()
{
try {
.....
}
finally {
......
}
}
}
The difference between the two is that this code instantiates the singleton the first time an object of that type is created where your code instantiates the singleton the first time SPEnvironment.Instance is accessed. In almost all cases, those are the same thing; in most of the remaining cases, it doesn't matter; but it is a subtle distinction that is worth understanding for that very rare edge case.

Categories

Resources