Jan Schreuder on .Net

.Net code samples, experiences, observations

View my professional profile on LinkedIn

Recent Posts

Tags

News

  • Inappropriate comments will be deleted at my discretion.

    The information and code samples in this weblog is provided "AS IS" without warranty of any kind, either expressed or implied, including but not limited to the merchantability and/or fitness for a particular purpose.

Community

Email Notifications

Tool suppliers

Tools

General

Microsoft

Favorite blogs

Archives

February 2008 - Posts

Dynamic type support in C# aka Late Binding

VB6 and VB.Net developers know this feature: "Late Binding" and C# developers have often ridiculed that option. Buit it seems that the next version of Visual Studio will support a feature called "Dynamic type support". An article on this new feature can be found here, at Charlie Calvert's Community Blog. James Manning likes the idea but has some remarks about the suggested implementation. You can read about that here.

Currently, C# developers will need to use reflection to instantiate the object and discover methods and properties. The way the C# team are thinking about the implementation will make dynamic objects work something like this:

static void Main(string[] args)
{
    dynamic
    {
        object myDynamicObject = GetDynamicObject();
        myDynamicObject.SomeMethod();         // call a method   
        myDynamicObject.someString = "value"; // Set a field
        myDynamicObject[0] = 25;              // Access an indexer
    }
}

If you've worked with reflection before, you immediately see how simple this will be. And the way it will be integrated into the CLR will allow other languages to use this as well.

Looks like another promising feature for C#!

Posted: Thu, Feb 21 2008 1:41 PM by Jan Schreuder | with no comments
Filed under: ,
SQL Server 2008 February CTP is available for download

Just found this on Dan''s Blog, the SQL Server 2008 CTP is available for download. If you're interested in the latest version of SQL Server, then follow any of the links below.

  • The download can be found here
  • If you want to know what's new in this CTP, look here
  • Product information, marketing papers, webcasts and videos on SQL Server 2008 can be found at the SQL Server 2008 product web site
  • Samples of SQL code can be found on CodePlex

 

Microsoft SysInternals

I was pointed to the Sysinternals section on TechNet recently. I've seen some of the tools provided there before, but I always seem to forget where I could find them. So now, as a permanent reminder, a short blog post. From the Sysinternals website:

The Sysinternals web site was created in 1996 by Mark Russinovich and Bryce Cogswell to host their advanced system utilities and technical information. Microsoft acquired Sysinternals in July, 2006. Whether you’re an IT Pro or a developer, you’ll find Sysinternals utilities to help you manage, troubleshoot and diagnose your Windows systems and applications. If you have a question about a tool or how to use them, please visit the Sysinternals Forum for answers and help from other users and our moderators.

 

Keep track of data changes using a SQL trigger

In my current project, we calculate the status of tasks that a user needs to do and store the status in a table. This happens on a daily basis. Once every week, we calculate which items are overdue and inform the user by email to take appropriate action. However, sometimes our users complain that they receive such an email and that there aren't any tasks that require immediate action.

We know that this happens, but since we calculate the status once per day and when the user logs on to the application, we cannot really see why this happens. What we needed was a way to see when a tasks moves to another state. We decided to create a history table which contains the information in our status table and update that history table using a trigger. But the examples we found in Books on Line and other resources on the web just didn't give us the information we needed.

So I called my good friend Patrick Wellink who I know to be a SQL guru. He had written a generic trigger which can be used to audit changes and posted this on SqlServerCentral.Com. The script looks like this:

CREATE TRIGGER TRG_##YOUR_TABLE##
ON [DBO].[##YOUR_TABLE##]
FOR DELETE,INSERT,UPDATE
AS
-- JUST CHANGE ##YOUR_TABLE## INTO YOUR OWN TABLENAME TO MAKE IT WORK 
DECLARE @ACT CHAR(6)
DECLARE @DEL BIT
DECLARE @INS BIT 
DECLARE @SQLSTRING VARCHAR(2000)
 
SET @DEL = 0
SET @INS = 0
 
IF EXISTS (SELECT TOP 1 1 FROM DELETED) SET @DEL=1
IF EXISTS (SELECT TOP 1 1 FROM INSERTED) SET @INS = 1 
 
IF @INS = 1 AND @DEL = 1 SET @ACT = 'UPDATE'
IF @INS = 1 AND @DEL = 0 SET @ACT = 'INSERT'
IF @DEL = 1 AND @INS = 0 SET @ACT = 'DELETE'
 
IF @INS = 0 AND @DEL = 0 RETURN
 
IF NOT EXISTS (SELECT * FROM SYSOBJECTS WHERE ID = OBJECT_ID(N'[DBO].[AUDIT_##YOUR_TABLE##]') AND OBJECTPROPERTY(ID, N'ISUSERTABLE') = 1)
BEGIN
    -- CREATE A MEMORY TABLE CONTAINING THE FIELDS AND TYPES OF THE TABLE
    DECLARE @MEMTABLE TABLE
    ( 
        ID INT IDENTITY
        ,COLUMNAME SYSNAME
        ,TYPENAME VARCHAR(20)
     )
    -- INSERT THE COLUMNAMES AND THE DATATYPES
    INSERT @MEMTABLE 
        (COLUMNAME,TYPENAME) 
        SELECT NAME,TYPE_NAME(XTYPE) 
        FROM SYSCOLUMNS 
        WHERE ID = OBJECT_ID('[DBO].[##YOUR_TABLE##]') 
        ORDER BY COLID
 
    DECLARE @CUR INTEGER
    DECLARE @MAX INTEGER
    DECLARE @SQLSTR AS VARCHAR(8000)
    DECLARE @CURCOL SYSNAME
    DECLARE @COLTYPE AS VARCHAR(10)
 
    -- SETUP VARIABLES
    SET @SQLSTR = ''
    SET @CUR=1
    SELECT @MAX = MAX(ID) FROM @MEMTABLE
 
    -- LOOP EVEY FIELD
    WHILE @CUR <= @MAX
    BEGIN
        -- GET VALUES FROM THE MEMTABLE    
        SELECT @CURCOL = COLUMNAME,@COLTYPE = TYPENAME FROM @MEMTABLE WHERE ID = @CUR
        IF @COLTYPE = 'INT' OR @COLTYPE = 'BIGINT' OR @COLTYPE='UNIQUEIDENTIFIER'
            -- WE DO WANT TO COPY INT/BIGINT/UNIQUEIDENTIFIER FIELDS BUT IF THEY ARE AN 
            -- IDENTITY OR A ROWGUIDCOLUMN WE DO NOT WANT TO COPY THAT ATTRIBUTES 
            SET @SQLSTR = @SQLSTR + ' CAST('+@CURCOL + ' AS '+@COLTYPE+') AS [' + @CURCOL +'] '
        ELSE
            -- ANOTHER FIELD DO NOTHING JUST COPY IT AS IT IS
            SET @SQLSTR = @SQLSTR + ' '+@CURCOL + ' AS [' + @CURCOL +'] '
        IF @CUR <= @MAX - 1 SET @SQLSTR=@SQLSTR + ','
        SET @CUR = @CUR + 1
    END
    -- ADD THE AUDIT FIELDS
    SET @SQLSTR = @SQLSTR +',CAST(''      '' AS CHAR(6)) AS TRG_ACTION,CAST(GETDATE() AS DATETIME) AS TRG_DATE'
    -- SET UP THE SELECT FOR CREATING THE AUDIT TABLE
    SET @SQLSTR = 'SELECT TOP 0 ' + @SQLSTR + ' INTO [DBO].[AUDIT_##YOUR_TABLE##] FROM [DBO].[##YOUR_TABLE##]'
    EXEC(@SQLSTR)
END
 
IF @ACT = 'INSERT' INSERT [DBO].[AUDIT_##YOUR_TABLE##] SELECT *,'INSERT' ,GETDATE() FROM INSERTED
IF @ACT = 'DELETE' INSERT [DBO].[AUDIT_##YOUR_TABLE##] SELECT *,'DELETE' ,GETDATE() FROM DELETED
IF @ACT = 'UPDATE' INSERT [DBO].[AUDIT_##YOUR_TABLE##] SELECT *,'UPDATE' ,GETDATE() FROM INSERTED

It does almost everything we needed. It copies the information to a new table when something happens to the row in the original table. Thanks Patrick for helping us with this script.

We modified the code for the update section, because we only wanted to store the old information in the AUDIT table when certain fields are modified:

INSERT [DBO].[AUDIT_##YOUR_TABLE##] 
SELECT DELETED.*,GETDATE()
FROM INSERTED
INNER JOIN DELETED ON DELETED.StatusID = INSERTED.StatusID 
WHERE (INSERTED.Status <> DELETED.STATUS) 
OR (INSERTED.CountAlerts <> DELETED.CountAlerts) 
OR (INSERTED.AlertViewed <> DELETED.AlertViewed)

This way, we get the information as it was before the update and only when the fields that we want to monitor are changed. Works great!

Finding Memory Leaks in WPF-Based applications

No matter what people say, managed code applications can (and will) leak memory. I bumped into a blog post on MSDN today which describes how memory leaks in WPF applications can be avoided and found should they occur. From the blog post:

In this blog I wanted to:

  • Show coding practices that can cause memory leaks which are more unique to WPF-base apps
  • Show how to avoid these leaks
  • Discuss the tools and techniques available to detect the leaks

The article contains links to tools that can help you track memory leaks. It also contains links to other resources about this subject. Be sure to check it out if you experience memory problems in your managed code.

You can find the article with all the information here: http://blogs.msdn.com/jgoldb/archive/2008/02/04/finding-memory-leaks-in-wpf-based-applications.aspx

The 9 worst Microsoft products ever?
Everyone is entitled to his/her opinion. The author of this article certainly has an opinion about a number of Microsoft products. There are even some products I had never heard of before. The list contains the following Microsoft products:
  1. Actimates
  2. Microsoft Home Routers
  3. Microsoft Mira
  4. Microsoft Origami
  5. Microsoft SPOT watch
  6. Microsoft BOB
  7. Microsoft Vista Ultimate
  8. The MSN Music Store and "Plays for Sure" audio format.
  9. The Microsoft Surface PC

Like I said, it's the authors opinion, not mine. I was surprised that Windows ME wasn't in the list, as were other people around me. I guess we all have a Microsoft product we'd like to see on this list.