|
Is it obvious? We could very easily be using Ingres and Oracle. Don't take too much for granted!
I know we could do a ddl export or similar from sql server - but it's not from that side. Currently we are using ODBC, but that will change over to using the proper Ingres .net stuff when we get our hands on it. We are currently looking at a couple of different platforms because in the end some of it is going to be running on a PDA.
Your answer is fair, but is actually to a different question I didn't ask.
To restate what I meant because I didn't put myself over that clearly:
1. Dynamic SQL Dataprovider <-> .Net datatype mapping - so we can dynmacially construct "CREATE TABLE" commands with the proper datatypes for that provider from column headings and .Net datatypes from the Dataset.
2. Possibility of using a Dataset to actually create a table rather then updating / deleting entries. (Long shot and probably not possible in anyway).
I think you gave your opinon on 2 - which is that it is impossible.
(1) Is fustrating because MS even publish a lovely table mapping types, and as I said the framework itself must know what .Net type relates to which SQL type for the provider or the Dataset wouldn't work in the first place:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconmappingnetdataproviderdatatypestonetframeworkdatatypes.asp
/**********************************
Paul Evans, Dorset, UK.
Personal Homepage "EnjoySoftware" @
http://www.enjoysoftware.co.uk/
**********************************/
|
|
|
|
|
Actually, I said it's not possible with the classes in the BCL (base class library). You could make (or a third-party library may already exist) a class (or classes) that takes those mappings and generates and / or executes the appropriate CREATE TABLE or ALTER TABLE commands.
It was obvious you were using SQL Server because you were refencing the System.Data.SqlClient classes! They only work for SQL Server (specifying any other OLE DB provider throws an exception when initializing a SqlConnection . If you don't want to use SQL Server, you MUST use the System.Data.OleDb namespace classes (or a custom provider implementation, such as ODBC.NET or Oracle.NET - others also exist in beta form last time I checked-up on them).
The SQL classes do understand the data-types as you suspect (and it is well-documented). This comes at an expense, though. Instead, you should consider using strongly-typed DataSet classes when possible. This makes table and column lookups - as well as field resolution - must faster and more type-friendly. For instance, many people always use DataRow[string] to get a column value, but this is very expensive because it must enumerating the columns each time to find the column with that name. There are ways to make this faster (such as caching the column index for that name), but strongly-typed DataSet classes do something similar automatically (technically, they already know the column indexes).
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
This is the code I have always used for a singleton.
public sealed class Singleton
{
private Singleton(){}
public static readonly Singleton Instance = new Singleton();
}
I am just getting into multithreading. I have read conflicting opinions on whether or not the code above is thread-safe?
Robert Zurer
robert@zurer.com
|
|
|
|
|
statics are initialized with the Type , but the above code won't get you a singleton. The code below is oft-used and recommended by Microsoft for the .NET Framework:
public sealed class Singleton
{
private static Singleton instance;
private Singleton() {}
private static Singleton Instance
{
get
{
if (instance == null)
lock (typeof(Singleton))
if (instance == null)
instance = new Singleton();
return instance;
}
}
private void doSomething()
{
Console.WriteLine("Something done.");
}
public static void DoSomething()
{
Instance.doSomething();
}
} Notice how the public methods are static? In most cases, this is what you want because you control what the caller can do. The Instance property is a thread-safe initializer that makes sure that only one instance is created. Your public static methods use that property (which will initialize the class instance if necessary) to call private instance methods or use private instance properties or fields. That is a singleton.
Keep in mind that the methods themselves are not thread-safe this way, though. To do that, you'll either want to use the lock keyword (on a static object, like the typeof(Singleton) I used, or this for instance methods / property accessors).
Now, you can accomplish this another way by using a ContextBoundObject where you can intercept calls but to the caller - it's just creating a new instance (where you return an existing instance). This gets into remoting issues which are more advanced, so you should probably try this out first. It's by far easier and accomplishes the same task.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
good call! Like that.
You may want to look at the lock hint pattern, so it doesn't have to do the mutex lock each time.
/**********************************
Paul Evans, Dorset, UK.
Personal Homepage "EnjoySoftware" @
http://www.enjoysoftware.co.uk/
**********************************/
|
|
|
|
|
Not familiar with that, but in this case the lock is not performed each time. Once the instance is non-null, the rest of the condition block isn't executed.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
you kind of did it, but without the boolean flag.
It's name is the "The Double-Checked Locking Pattern"
Example implementation here:
http://www.cuj.com/documents/s=8047/cuj9910ringle/
It comes from this academic paper (although the link is dead you can find it if you hunt about a bit):
[5] Douglas Schmidt and Tim Harrison. "Double-Checked Locking: An Optimization Pattern for Efficiently Initializing and Accessing Thread-safe Objects," http://www.cs.wustl.edu/~schmidt/DC-Locking.ps.gz
/**********************************
Paul Evans, Dorset, UK.
Personal Homepage "EnjoySoftware" @
http://www.enjoysoftware.co.uk/
**********************************/
|
|
|
|
|
I did do the double-checked locking mechanism! Look at my code again:
if (instance == null)
lock (typeof(Singleton))
if (instance == null)
instance = new Singleton(); Looks like double-checked locking to me, and was called such (couldn't remember what the "technical" term) in a Microsoft article published in the 1.0 beta days.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Indeed, as I said, you did it without the boolean flag. Kudos.
/**********************************
Paul Evans, Dorset, UK.
Personal Homepage "EnjoySoftware" @
http://www.enjoysoftware.co.uk/
**********************************/
|
|
|
|
|
Sorry, I misunderstood one of your posts (well, maybe). As far as a boolean flag goes, though, the way I used a conditional would result in few instructions and field members. Having a separate field just to remember this would increase the size of the Type, and having to set that in addition to instantiating the singleton class is yet a few more instructions:
ldarg.0
ldc.i4.1
stfld Singleton.initialized
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
You mention that the methods themselves are not thread-safe. Do you mean that the method
public static void DoSomething() <br />
{ <br />
Instance.doSomething(); <br />
}
Should be
public static void DoSomething() <br />
{ <br />
lock (typeof(Singleton))<br />
Instance.doSomething(); <br />
}
even though Instance itself is protected by a lock?
|
|
|
|
|
The instance is not protected by a lock - the initialization of the Singleton was protected by a lock, but that was just to make sure that only one instance of the Singleton class was initialized. See the discussion Paul and I are having on this thread for more info.
Also, it is not necessary to lock every static method - only if you need to synchronize access to a resource. For doing something as simple as a calculation that doesn't use instance resources, you don't need to, like:
public static int Add(int a, int b)
{
return a + b;
}
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
In this case, my Singleton will be used to synchronize access to a centralized Hashtable which holds the 'clean' or saved values of properties of objects while the actual objects are being validated, persisted and then finally updated if all goes well. After the update succeeds the values are removed from the hash table.
The aim is to allow multiple threads to be able to have read consistency while a write is going on. I want to accomplish this by deriving all my business from ContextBoundObject.All calls to set methods would be intercepted and the existing values added to this Hashtable(keyed to a global object id).
When another thread wants to read, the get method is intercepted, and, in SyncProcessMessage, the MessageSink checks for an entry in this Hashtable, if one is found, the value of the property is taken from the Hashtable and passed to the caller, otherwise it passes the IMessage unaltered.
I assume this Hashtable qualifies as a resource.
But this brings up another two questions.
1 - By using ContextBoundObject am I in some way automatically serializing access? and if not
2 - Must I place a lock within SyncProcessMessage?
|
|
|
|
|
I don't know if you want to mess with a ContextBoundObject in this case. It's a lot of overkill. For instance, you want the value to always be available whether or not it exists first (or something like that). Use myHashtable[key] = value . If the key exists, the value is changed. If it doesn't exist, the key is added and the value is still set. Using a ContextBoundObject also means that the objects you're passing around have to be serializable and this mechanism is a little slower (as you have probably figured out) that direct calls.
As far as threading the Hashtable goes, you should actually lock against Hashtable.SyncRoot , or use the synchronized Hashtable returned from the static method Hashtable.Synchronized(myHashtable) .
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
By why do we need the "instance" in a singleton at all? Making the methods static seems to be enough:
<br />
public sealed class SingletonNoInstance<br />
{<br />
private static Object m_objInit = new InitObj();<br />
<br />
private static Object InitObj()<br />
{<br />
return new Object(); <br />
}<br />
<br />
public static void ThreadSafeDoSomething() <br />
{ <br />
lock(typeof(SingletonNoInstance))<br />
{<br />
}<br />
}<br />
}<br />
The private member m_objInit and method InitObj() can be removed if no initialization of the class is required.
|
|
|
|
|
There's a difference between singletons and a class with static methods. If you just have simple static methods (like the System.Math class), you don't need to construct a singleton. Singletons are useful when you want lots of different callers to use the same resource without having multiple instances of that resource (or the class that has that resource). For instance, all throughout the .NET BCL (and our application I architected), most classes in an assembly use a internal singleton that has a single instance of a ResourceManager that contains strings (and other resources at times) for all classes to use (like common exception messages or property categories and descriptions). It would be horribly inefficient to have an instance of this ResourceManager for each class (and who knows how many instances of each class?!), so they use a singleton with a single instance of the ResourceManager .
There are many other reasons for singletons (if you know anything about remoting, there's some good examples for that, too). This is just a common example I think of because I use it a lot and it is far more efficient to do it this way that for each instance of a class to have it's own - especially when you're sharing string resources amongst other classes.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
In doing further reading, I came upon Jon Skeet's excellent article.
http://www.yoda.arachsys.com/csharp/singleton.html
Unless I'm reading him incorrectly, the fourth version of the Singleton he presents is the same code I have been using.
public sealed class Singleton<br />
{<br />
private Singleton(){}<br />
public static readonly Singleton Instance = new Singleton();<br />
}
He calls it "thread-safe without using locks". What I understand from his article is that this thread-safety is due to the way the Framework handles static type initializers. Have I missed something?
|
|
|
|
|
You'll also notice he calls it "lazy". Besides, you still need to add the static constructor so the correct IL is generated.
The biggest difference between this and the way we were previously talking about (double-checked locking) is that static constructors as executed at most once per application domain. This means that your Singleton will be a different singleton in each AppDomain your application uses (in a distributed app that uses Remoting or Web Services, there is at least two AppDomain , and even a your process can create additional AppDomain on the same machine).
One important thing to keep in mind - the performance penalties for the double-checked locking are negligible - it only locks once and the first conditional statement is a one-line instruction in IL and is extremely quick. This is the proper way to do it. Lazy programming leads to bugs and holes.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Very cool.
The clouds have parted.
I will not be traversing AppDomains but I will be accessing the singleton from a ServerContextSink.
I don't know whether that would also defeat the thread-safety of the first method, but as you say the performance hit for the lock is negligible (certainly negligible compared to the 1000% hit I seem to be taking instantiating ContextBoundObject), I will definite use double-checked locking.
Robert Zurer
robert@zurer.com
|
|
|
|
|
Hi guys...
I've created a setup project using VS.NET. It works fine, change some registry keys, create my database (using my installer class), creates some IIS virtuals dirs. The problem is that I need to force the machine to reboot after the installation has been completed. Does anyone know how to to this ? Is there any parameter I can change in my installer class to do this ?
thanks in advance
Mauricio Ritter - Brazil
Sonorking now: 100.13560 MRitter
English is not my native language so, if you find any spelling erros in my posts, please let me know.
|
|
|
|
|
I just covered this a day or two ago (searching first is always a good idea). Set the REBOOT property (must be all upper-case) to Force. See the Windows Installer SDK for more information.
Since VS.NET's setup projects suck, you'll have to download Orca (part of the Windows Installer SDK, which is part of the Platform SDK) and make the changes post-build. Just open the MSI package, find the Properties table, and add said property. You could also do this using a custom action, but it's quite a bit of overhead for a such a simple task.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Heath Stewart wrote:
You could also do this using a custom action, but it's quite a bit of overhead for a such a simple task.
Actually I already have a installer class with custom actions in my setup project, it would be easier to insert the property there, I just don't know where to insert it. I tryed the Context.Parameters collection but it didn't work. Any ideias ?
Mauricio Ritter - Brazil
Sonorking now: 100.13560 MRitter
English is not my native language so, if you find any spelling erros in my posts, please let me know.
|
|
|
|
|
You can't, actually. .NET Installer classes have nothing to do with Windows Installer, Windows Installer is just able to run them as custom installer actions. I was talking about native custom actions that you'd have to write in C/C++ (with C-style functions).
The easiest way is to install Orca and edit the MSI yourself. Just go to mdsn.microsoft.com and go to downloads. Click Platform SDK but only install the Windows Installer SDK. It will install only a few required components from the PSDK itself. Legally, I cannot just send you the installer for Orca but it is an invaluable tool and is worth the download if you're messing with installer packages.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
C++ has its STL for doing stuff like linked lists etc.
What about .NET? I need data structures to dynamically manage lots of different objects. Are the Collections fast enough?
Which types of what are found in .NET are suitable for real-time applications that need to create and destroy lots and lots of objects very fast? at the same time the garbage collector also should not interfere too much. Hopefully it will be unnoticable.
Any suggestions from your experience? What should I prefer.
|
|
|
|
|
Well an example could be: performance of stl::list vs. .NET collections?
Application: real-time simulator
Thank you!
|
|
|
|