Saturday, April 16, 2011

Lazy: What it is and why you should be using it

Lazy<T> allows you to write code that not only executes on an as-needed basis, but is also guaranteed to be thread safe.  I've put together a demo application that includes a couple unit tests as well as console output to demonstrate using simple lazy initialization (which does work great for single-threaded apps) versus Lazy<T> initialization.

Basic lazy loading:
private object _obj;
public object MyObject
{
  get  {
    if (_obj == null)
      _obj = new object();
  
    return _obj;
}

Lazy<T> loading:
private Lazy<object> _obj = new Lazy<object>();
public object MyObject { get { return _obj.Value; } } //Lazy<T> guarantees that this will always return the same value

Note that this simple example is using a static initializer for _obj, I've found myself initializing Lazy<T> properties in the constructor much more often than using the static initialization, but in the spirit of a demo here we are.  In my demo solution I do indeed initialize the private Lazy<T> var in the constructor.

The basic lazy loading example above is not thread-safe, in a single threaded application it will behave just as you would expect when you look at the code, but in a multi-threaded application the MyObject property will often return different objects across threads.  This is due to the fact that multiple threads can evaluate the 'if (_obj == null)' statement prior to _obj being initialized.

The demo I put together can be found here: http://cid-edc8bd4a11230d7b.office.live.com/self.aspx/.Public/blog/LazyT.zip

Creating a SQL Server login (windows account) without server admin rights

The default install configuration for SQL Server used to add the builtin\admin group to the server admin role, this is no longer the case with SQL Server 2008 and often causes the user installing SQL to be the only user that has any access to SQL.  Not usually an issue when you're doing your own install, but if someone else configures your developer machine(s) you can be a bit stuck.

It's been a while since I ran this, but if I recall correctly, here are the steps to get yourself added as a server admin.

1.  Shutdown SQL, this can be done in the SQL Server Configuration Manager or from the command prompt (if you have UAC enabled, you will need to run your command prompt with Administrative permissions).
  Example commands from technet:
  net stop MSSQLSERVER  or net stop MSSQL$instancename
  http://technet.microsoft.com/en-us/library/ms190236.aspx

2.  Start an instance of SQL running under your current windows user account, replace <MachineName> with computer name found under system properties and <InstanceName> with the name of your SQL instance.  If you're using the default install settings, MSSQL is the default (SQLEXPRESS if using the express version of SQL).

This is the location of my SQL executable (and therefore where I opened my command prompt to): C:\Program Files\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQL\Binn>
In a command prompt (path set to MSSQL\Binn directory), enter:
sqlservr.exe -S <MachineName>\<InstanceName> -E

If successful, you should get a 'SQL Server' popup/dialog with an OK button, do NOT click OK until we are finished with our 2nd command prompt.3.  With the command prompt still open for step 2, open a new command prompt, and execute the following script/command.  Note: I'm using 'WEBERNET' for my domain and 'TWEBER' for my user in this example.  I have not attempted using this script outside of a domain, but my guess is that the domain can simply be replaced with the computer name if the computer or user is not part of a domain.



sqlcmd -S <MachineName>\<InstanceName> -E

CREATE LOGIN [WEBERNET\TWEBER] FROM WINDOWS
GO

exec sp_addsrvrolemember @loginame='WEBERNET\TWEBER', @ROLENAME='sysadmin'
go
 
4.  And we're done, go ahead and click OK on the SQL dialog and start SQL again as normal (net start MSSQL$SQLEXPRESS).

Microsoft does have a script available for doing this same thing on SQL Express, I haven't tried it out yet though nor do I know if it also works with the standard SQL install.

http://archive.msdn.microsoft.com/addselftosqlsysadmin/