NetInverse Developers Blog

March 9, 2009
Category: .Net — Tags: , , — admin @ 12:16 am

Following code doesn’t compile:

    class GenericFactory where T : new()
    {
        public T Create(object a, object b)
        {
            return new T(a, b);
        }
    }

The compiler will give you following error message: “‘T’: cannot provide arguments when creating an instance of a variable type.”. Well, there are a couple ways to solve this issue.

Use reflection

    class GenericFactory
    {
        public T Create(object a, object b)
        {

            return (T) typeof(T).GetConstructor(
   new System.Type[] { typeof(object), typeof(object) }).Invoke(new object[] {a, b});
        }
    }

Use intialization

Following code uses an initialization interface to solve this issue. You can also use properties instead of a method.

    interface I
    {
        void Initialize(object a, object b);
    }

    class GenericFactory where T : I, new()
    {
        public T Create(object a, object b)
        {
            T t = new T();
            t.Initialize(a, b);
            return t;
        }
    }
Category: .Net — Tags: , — admin @ 12:12 am

In case you see following error, you can bypass the .Net Strong name verification. 

Unhandled Exception: System.IO.FileLoadException: Could not load file
or assembly 'FunkyProg, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089' or one of its dependencies.
Strong name validation failed. (Exception from HRESULT: 0x8013141A)

File name: 'FunkyProg, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089' ---> System.Security.SecurityException:
Strong name validation failed. (Exception from HRESULT: 0x8013141A)

The Zone of the assembly that failed was:

MyComputer

You can use sn.exe to register <assembly> for verification skipping.

 sn -Vr <assembly> [<userlist>] [<infile>]

Or you can add following entry to the registry(you need to put the right public key token value).

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\StrongName\Verification\*,b77a5c561934e089]

b77a5c561934e08 is the PublicKeyToken for the assembly.

March 8, 2009
Category: Build — Tags: , , — admin @ 8:37 pm

I converted an old VS2003 project into VS2005 and tried to build it with an existing Nant build script. Nant started to fail with a following error: Error loading GUID of project…

NAnt 0.85 (Build 0.85.2470.0; nightly; 10/6/2006)
Copyright (C) 2001-2006 Gerry Shaw
http://nant.sourceforge.net
Buildfile: file:///C:/projects/MyProject.build
Target framework: Microsoft .NET Framework 2.0
Target(s) specified: Build  
    [echo] Using 'net-2.0' framework on 'win32' platform.
Build:
BuildProjects:
[echo] Current base directory: .
[echo] Building all projects under base directory...
[solution] Starting solution build. 
BUILD FAILED - 0 non-fatal error(s), 1 warning(s)
Error loading GUID of project 'C:\MyProject\DBAccess.csproj'.
Couldn't locate ProjectGuid in project 'C:\MyProject\DBAccess.csproj'
Total time: 0.8 seconds.

My build file as below was working before I converted the project using VS2005.

        <target name="Build">
          ...
            <solution configuration="${configuration}">
                <projects basedir="${basedir}">
                    <include name="**\*.csproj"/>
                </projects>
            </solution>
        </target>

After digging into the Nant online doc, I found that the current version of Nant doesn’t support VS2005 project . Visual Studio 2005 uses the MSBuild project file to store build information about managed projects. Project settings added and changed through Visual Studio are reflected in the .*proj file that is generated for each project. Visual Studio uses a hosted instance of MSBuild to build managed projects, meaning that a managed project can be built in Visual Studio and from the command line (even without Visual Studio installed), with identical results. Thus the solution is use MSBuild to build VS2005 project file. I changed the Nant script as below:

        <target name="exec-msbuild">
            <exec program="msbuild"
                commandline='"${solution.file}" /v:q /nologo
    /t:${solution.target} /p:Configuration=${configuration}' />
        </target>

Now my project successfully migrated to VS2005 and .Net 2.0.

Category: Windows API — Tags: , , — admin @ 8:24 pm

GetLogicalProcessorInformation: Retrieves information about logical processors and related hardware.

You can use this new API easily to detect how many CPUs or Cores on your machine. Otherwise, you may have to deal with CPUID with the Intel and AMD extensions. You can also use this API to find out which virtual processors are associated with the same physical processor.

Example from MSDN

    #include <windows.h>
    #include <malloc.h>
    #include <stdio.h>
    #include <tchar.h>

    typedef BOOL (WINAPI *LPFN_GLPI)(
        PSYSTEM_LOGICAL_PROCESSOR_INFORMATION,
        PDWORD);

    int _cdecl _tmain ()
    {
        BOOL done;
        BOOL rc;
        DWORD returnLength;
        DWORD procCoreCount;
        DWORD byteOffset;
        PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer, ptr;
        LPFN_GLPI Glpi;

        Glpi = (LPFN_GLPI) GetProcAddress(
                                GetModuleHandle(TEXT("kernel32")),
                                "GetLogicalProcessorInformation");
        if (NULL == Glpi)
        {
            _tprintf(
              TEXT("GetLogicalProcessorInformation is not supported.\n"));
            return (1);
        }

        done = FALSE;
        buffer = NULL;
        returnLength = 0;

        while (!done)
        {
            rc = Glpi(buffer, &returnLength);

            if (FALSE == rc)
            {
                if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
                {
                    if (buffer)
                        free(buffer);

                    buffer=(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(
                            returnLength);

                    if (NULL == buffer)
                    {
                        _tprintf(TEXT("Allocation failure\n"));
                        return (2);
                    }
                }
                else
                {
                    _tprintf(TEXT("Error %d\n"), GetLastError());
                    return (3);
                }
            }
            else done = TRUE;
        }

        procCoreCount = 0;
        byteOffset = 0;

        ptr=buffer;
        while (byteOffset < returnLength)
        {
            switch (ptr->Relationship)
            {
                case RelationProcessorCore:
                    procCoreCount++;
                    break;

                default:
                    break;
            }
            byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
            ptr++;
        }

        _tprintf(TEXT("Number of active processor cores: %d\n"),
                 procCoreCount);
        free (buffer);

        return 0;
    }
Category: .Net — Tags: , , , , — admin @ 1:00 am

In C++, you can use Win32 WPI FormatMessage to get the system error message. So what is the equivalent in managed code?

It is easy! you can simply use Marshal.GetExceptionForHR.

Marshal.GetExceptionForHR Method (Int32):
Converts the specified HRESULT error code to a corresponding Exception object.

Namespace: System.Runtime.InteropServices
Assembly: mscorlib (in mscorlib.dll)

Sample code:

using System;
using System.Text;
using System.Runtime.InteropServices;

namespace hr
{
    class Program
    {
        static void Main(string[] args)
        {
            Exception e = Marshal.GetExceptionForHR(-2147024894);
            System.Console.WriteLine(e.Message);
        }
    }
}

Run above program you will get following system error message from the console:

The system cannot find the file specified. (Exception from HRESULT: 0×80070002)

Please note that when you call a COM object and want to get back the original HResult like S_OK and S_FLASE, you may need to use PreserveSigAttribute Class. Since most COM member return an HRESULT, by applying the PreserveSigAttribute, you can retrieve an integer representing the success or failure HRESULT.

Category: .Net — Tags: , , , , — admin @ 12:35 am

This tool fusion log viewer, coming with Microsoft .Net Framework SDK, is a very useful, but less known. It can display details for failed assembly binds. This information helps you diagnose why the .NET Framework cannot locate an assembly at runtime.

For example, you have written a .Net application and it works on your development machine perfectly. When you deploy it on a testing machine, it throws out exception about assembly binding failure. You know there might be a dependent DLL missing. But how do you figure out which one? use Fuslogvw.exe. It is very possible that in your code you interop some COM components, which have some dependent runtime DLLs are missing on your testing machine. Is it cool?

When you run fuslogvw.exe and it displays nothing, you need to add following flag to the registry.

       HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion

       Add a new DWORD key ForceLog, value = 1

You can check out some more details from this blog: Fuslogvw.exe and diagnosing .NET assembly binding issues. Suzanne Cook’s .NET CLR Notes is also a good resource of Common Language Runtime and binding issues.

Category: SQL — Tags: , , , , — admin @ 12:33 am

SQL server only allows you to restrict access to the table columns indirectly. The approach is create views and stored procedures and grant them to ceitain users. Now SQL 2005 allows you to manuplate column-level permissions directly. So let’s look at a SQL sample below:

        CREATE TABLE student (
            id      INT,
            name    NCHAR(20),
            ssn     VARCHAR(11)
        )

        INSERT INTO student
        (id, name, ssn) VALUES (1, 'david', '999-12-1234')

        GRANT SELECT (id, name) ON student TO [DAFFIDIO\David]
        DENY SELECT (ssn) ON student TO [DAFFIDIO\David] --DENY SELECT

        Execute AS LOGIN  = 'DAFFIDIO\David'-- IMPERSONATE
        SELECT SUSER_NAME(), USER_NAME()

        SELECT id, name FROM student

        SELECT ssn FROM student 

        REVERT  -- undo IMPERSONATE

Now David can see id and name, but not ssn. He will see an error message as below:

   Msg 230, Level 14, State 1, Line 2
   SELECT permission denied on column 'ssn' of object 'student',
   database 'Test', schema 'dbo'.

The syntax is:

        GRANT { ALL [ PRIVILEGES ] }
              | permission [ ( column [ ,...n ] ) ] [ ,...n ]
              [ ON [ class :: ] securable ] TO principal [ ,...n ]
              [ WITH GRANT OPTION ] [ AS principal ]

You can use GRANT, REVOKE AND DENY to set granular permissions on column level now.

Category: SQL — Tags: , , — admin @ 12:23 am

SQL server’s non cluster index has two limitations:

  • Only 16 columns can be included
  • The maxium size of the index key can be only 900 bytes

With SQL 2005, you can overcome these limitations by using INCLUDE:

CREATE INDEX IDX_FOO ON FOO (COL1, COL2) INCLUDE (COL3)

Category: SQL — Tags: , , , , — admin @ 12:16 am

What is a deadlock?

A deadlock occurs when two system server process IDs (SPIDs) are waiting for a resource and neither process can advance because the other process is preventing it from getting the resource. For example, Andrew holds a lock on table A and requests a lock on table B; Lindsay holds a lock on table B and requests a lock on table A.

The lock manager(Lock Monitor)’s thread checks for deadlocks. When a lock manager’s deadlock detection algorithm detects a deadlock, the lock manager chooses one of the SPIDs as a victim. The lock manager initiates a 1205 error message that is sent to the client, and the lock manager kills the SPID.

Transaction (Process ID %d) was deadlocked on {%Z} resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

Killing the SPID frees the resources and allows the other SPID to continue. In a well designed application, the front-end application should trap for the 1205 error, reconnect to SQL Server, and then re-submit the transaction. Although deadlocks can be minimized, they cannot be completely avoided. That is why the front-end application should be designed to handle deadlocks.

So what can cause deadlocks?

  1. Locks
  2. Worker threads
  3. Memory
  4. Parallel query execution-related resources
  5. Multiple Active Result Sets (MARS) resources.

How to debug deadlocks

Turn on deadlock trace

          DBCC TRACEON(1204,1222)

This will enable deadlock tracing for all existing connetions and new. You can check out KB832524 for more details. Trace flag 1204 reports deadlock information formatted by each node involved in the deadlock. Trace flag 1222 formats deadlock information, first by processes and then by resources.

Use SQL Profiler to trace deadlock events and get the resource ID of the table or index under contention. The steps to do this are:

  1. Start SQL profiler
  2. On the Trace Properties dialog box, on the General tab, check Save to file and specify a path to save the trace
  3. Click the Events tab, only add Locks\Lock:deadlock and Locks\Lock:deadlock chain
  4. Click the Data columns tab, add DatabaseID, IndexID, ObjectID

This trace will record all deadlocks on this SQL Server instance, along with the ID of the source table of contention. To translate the database id and object id into names (although DatabaseName and ObjectName are selectable columns, the data is not always presented in the trace), you can do

           SELECT database_name(DatabaseID)
           SELECT object_name(ObjectID)

Use SQL Profiler to trace batch statements or RPC statements, to trace which statement causes the deadlock. The restriction of this is that if the repro is far between and you have a busy system, the trace file will grow too large to be useful.

You can also run following query to check which process is being blocked.

            SELECT * FROM sys.sysprocesses WHERE blocked <> 0

            Get the SPID from blocked column

            DBCC inputbuffer (SPID)

            sp_who2

            sp_lock2

You can also use SP_LOCk2 to receive detailed locking view.

Please also check out Detecting and Ending Deadlocks on MSDN.

Category: .Net, SQL — Tags: , — admin @ 12:12 am

Query Notifications is a powerful new feature, built in to SQL 2005, usable from ADO.NET 2.0 and from ASP.Net 2.0 directly.

Query Notifications allows you send a query to SQL server and request that a notification be generated if any row included in the query is changed.

Commands sent to server may include a tag that requires a notification. Whe the server sees this tag, it will create a notification subscription that fires once the result set is change for the query statement.

This is extremely useful for client side caching of results from database server. With this feature, you don’t have to pulling data periodically.

« Newer PostsOlder Posts »

©2009 NetInverse. All rights reserved. Powered by WordPress