Singleton by Jon Skeet Clarification

C# - Singleton - do I need a constructor?

My question is, on .NET 4.0, should I include the constructors (I think they are now implicitly created).

Yes, there is no change in Fx4 or C# 4.

If you don't provide the instance constructor then the compiler provides a public one.

There is no reason to provide the static constructor.

The following seems to work just as well,

The point is that var s = new Singleton(); should not work. That's the thing to test.

C# BeforeFieldInit Jon Skeet explanation confusion

I'm not sure what question is being asked here; perhaps if I explain what is going on in the mind of the jitter, that will answer the question.

Static classes with an explicit static constructor have "strict" semantics about when the cctor runs: it runs immediately before the first use of a member of the type. So if you have

if (whatever) x = Foo.Bar;

then the cctor for Foo is NOT run if whatever is false, because we have not yet encountered an actual use of a member.

Think about what this must mean for the jitted code. How would you write a jitter for a language that has this requirement?

For static method calls you could put a little prequel at every call site that checks if the cctor has been run. But that makes every call site bigger and slower.

You could put the prequel into the static method itself. That would keep the call sites small, but every call would still get slightly slower.

Or, you could be clever and put the check in the jitter the first time the static method is jitted. That way you only get the cost of the check once, and call sites stay small. The jit cost gets larger, but only by a tiny fraction; jitting is already expensive.

Notice however that doing so precludes any optimization that causes a method to be jitted before its first call, because such an optimization now introduces a correctness problem. Optimization almost always involves trade-offs!

But for field accesses, there's no method to jit. The jitter would have to put a little prequel in front of every access to the field that could possibly be the first. So accessing a field not only gets slow, but the code also gets big.

You might think why not make the field into a property and put the prequel on the jitting of the getter and setter?, but that doesn't work because fields are variables and properties are not. We need to be able to pass static fields via ref and out, for instance, but you can't do that with a property. The field might be volatile, and cannot be a property. And so on.

It would be nice to be able to avoid these costs on field accesses.

Static classes without an explicit cctor but with a compiler-generated implicit cctor to initialize the static fields get "relaxed" semantics where the jitter merely guarantees that the cctor is called at some point before a field is accessed. Your program uses these relaxed semantics.

In the first version, with a field access, the jitter knows from its analysis of the method that a static field might be accessed. (Why "might"? As before, the access could be under an if.) The jitter is allowed to run the cctor at any time before the first access, so what it does is it makes a note that says when Main is jitted, check to see if the Test1 cctor has been run, and if not, run it.

If Main is called a second time, hey, it's only jitted once. So again, the cost of the check is only borne on the first call. (Of course Main is only ever called once in most programs, but you can write a recursive Main if you're into that sort of thing.)

In your second program there is no field access. The jitter could also reason that a static method is accessed, and that the cctor could be run at jit time for Main. It does not. Why not? I don't know; you'd have to ask the jitter team about that. But the point is that the jitter is entirely within its rights to use a heuristic to decide whether or not to run the cctor at jit time, and it does so.

The jitter is also within its rights to use a heuristic to decide whether or not a call to a static method that touches no field triggers the cctor; in this case apparently it does so, unnecessarily.

Your question seems to be "what are these heuristics?" and the answer is... well, I don't definitively know what the answer is, and it is an implementation detail of the runtime subject to change at its whim. You've seen in this answer what some good guesses are about the nature of those heuristics:

  • Check to see if the cctor of T needs running when any static method of T is jitted
  • Check to see if the cctor of T needs running when any method that accesses a static field of T is jitted

Those heuristics would fulfill the requirements of the relaxed semantics, and would avoid emitting all checks at call sites, and would still ensure reasonable behaviour.

But you can't rely on those guesses. All you can rely on is that the cctor will get run at some point before the first field access, and that's what you're getting. Whether or not there is a field access in a particular method is plainly a part of that heuristic, but those heuristics could change.

newbie playing with things that might be best avoided; adding a connection instance into a Singleton pattern

There are very few situations were a singleton pattern is appropiated. You have to be sure that there is a mandatory need of one and only one instance of a class instance. Normally you don't have this design requirement, but people tend to make it up.

Connections should be released as soon as you're done with your unit of work. You should not keep a connection open forever so converting your connection to a singleton won't help to improve your application design.

Connection pooling mechanism manage the complexity for you so you don't have to worry about performance in relation to open and close connections since this is optimized by design.

Connecting to a database server typically consists of several time-consuming steps. A physical channel such as a socket or a named pipe must be established, the initial handshake with the server must occur, the connection string information must be parsed, the connection must be authenticated by the server, checks must be run for enlisting in the current transaction, and so on.

In practice, most applications use only one or a few different configurations for connections. This means that during application execution, many identical connections will be repeatedly opened and closed. To minimize the cost of opening connections, ADO.NET uses an optimization technique called connection pooling.

Connection pooling reduces the number of times that new connections must be opened. The pooler maintains ownership of the physical connection. It manages connections by keeping alive a set of active connections for each given connection configuration. Whenever a user calls Open on a connection, the pooler looks for an available connection in the pool. If a pooled connection is available, it returns it to the caller instead of opening a new connection. When the application calls Close on the connection, the pooler returns it to the pooled set of active connections instead of closing it. Once the connection is returned to the pool, it is ready to be reused on the next Open call.

Source MSDN

Singleton pattern - a simplified implementation?

On site https://sharplab.io you can look at IL code, in both cases IL code are similar. So this should work same way.



Related Topics



Leave a reply



Submit