Labels

Tuesday, March 31, 2009

Static Class & Construtor Myth

Static Class & Construtor Myth

 

Static class cannot have instance constructors.

A static member cannot be marked as override, virtual, or abstract.

 

 

static class Testlab

    {

        public Testlab()  // Error

        { }

 

        public static string myMehtod()

        {          

            return "";

        }

    }

 

 

 

 

 

 

 

More details are pemding … Will update shortly…

 

Regards,

Arun Manglick

 

 

 

Variable Declaration Or Initialization within Try Block - Myth

Hi,

 

Here the articles covers whether the variables declaration within the try block is correct practice or not.

Reference: http://msdn.microsoft.com/en-us/library/0yd65esw(VS.80).aspx

 

-          Inside a try block, declare only those variables that are not required to be access outside the try i.e. neither in catch nor in finally. See below ‘The name 'dt does not exist in the current’.

-          When inside a try block, only initialize variables that are declared therein; otherwise, an exception can occur before the execution of the block is completed. See below ‘Use of unassigned local variable’.

 

 

 

 

 

 

try

{

    DataTable dt = new DataTable();

}

catch (Exception ex)

{

    // Error - The name 'dt does not exist in the current }

finally

{

    Dt.Dispose() // Error - The name 'dt does not exist in the current

}

 

 

public int Me()

{

    int x;

    try

    {

        // Don't initialize this variable here.

        x = 123;

    }

    catch

    {

    }

 

  return x; // Error: Use of unassigned local variable 'x'.

}

 

 

 

 

 

Regards,

Arun Manglick

IDisposable & Dispose Myth


IDisposable & Dispose Myth

Why Required – Even when GC is there ??

The garbage collector automatically releases the memory allocated to a Managed Object when that object is no longer used, though, it is unpredictable when garbage collection will occur.
But , the garbage collector has no knowledge of Unmanaged Resources.

Unmanaged Resources are –

-          Window handles,
-          File handles - open files and streams
-          Network connections, and
-          Database connections.

When managed classes encapsulate direct or indirect references to unmanaged resources, you need to Make Special Provision To Ensure The Unmanaged Resources Are Released when an instance of the class is garbage collected.

The mechanisms are:

-          Declaring a destructor (or finalizer) as a member of your class.
-          Implementing the System.IDisposable interface in your class.

Destructor Approach –

It has two disadvantages –

-          Undeterministic - C# destructors are used far less than their C++ equivalents. The problem with C# destructors when compared with their C++ counterparts is that they are non deterministic. When a C++ object is destroyed, its destructor runs immediately. However, because of the way the garbage collector works, there is no way to know when an object’s destructor will actually execute.

-          Requires two Pass –
o        Objects that do not have a destructor get removed from memory in one pass of the garbage collector.
o        But objects that have destructors require two passes to be destroyed: the first one calls the destructor and move the object to the finalization queue without removing the object, the second actually deletes the object.



-          Here when garbage collector runs for the first time it searches for objects whose memory has to freed.
-          He sees three objects but only cleans the memory for Object1 and Object3.
-          Object2 it pushes to the finalization queue.
-          Now garbage collector runs for the second time. He see’s there are no objects to be freed and then checks for the finalization queue and at this moment it clears object2 from the memory.

So if you notice that object2 was freed from memory in the second round and not first


IDisposable Approach –

Note -
-          While implementing Dispose() method of the IDisposable Interface – Make sure that the method is not  decalred to be virtual. A derived class should not be able to override this method.
-          Dispose is required to be called explicitly. Or it can be called automatically if used in the ‘Using’ block.

Imp – Use of ‘Using ‘ block requires the Object to implement ‘IDisposable’ interface.



public class MyResource : IDisposable
    {
        private IntPtr handle;  // Unmanaged resource.
        private Component component = new Component(); // Managed resource             
        private bool disposed = false; // Track whether Dispose has been called.

        public MyResource(IntPtr handle)
        {
            this.handle = handle;
        }

        // Do not make this method virtual. A derived class should not be able to override this method.
        public void Dispose()  // IDisposable Implementation
        {
            MyDispose (true);
            GC.SuppressFinalize(this);
        }

        private void MyDispose(bool thruDispose)
        {           
            if (!this.disposed) // Check to see if Dispose has already been called.
            {
                // If disposing equals true, dispose all Managed and Unmanaged resources.
                if (thruDispose)
                {
                    component.Dispose(); // Dispose Managed resources.
                }

                // Now Cleanup Unmanaged resources. If disposing is false, only the following code is executed.
                CloseHandle(handle);
                handle = IntPtr.Zero;
            }
            disposed = true;  // Mark that Dispose has been called
        }

        // Use interop to call the method necessary  to clean up the unmanaged resource.
        [System.Runtime.InteropServices.DllImport("Kernel32")]
        private extern static Boolean CloseHandle(IntPtr handle);

        // This destructor will run only if the Dispose method does not get called.
        ~MyResource()
        {
            // Do not re-create Dispose clean-up code here.
           // Calling Dispose(false) is optimal in terms of readability and maintainability.
            MyDispose (false);
        }
    }



Usage – Explicit Approach

    Resource theInstance = null;
    try
    {
            theInstance = new Resource();
    }
    finally
    {
            if (theInstance != null)
            {
                theInstance.Dispose();  // Calling Explicity
            }
    }

Usage – Implicit Approach

using (Resource theInstance1 = new Resource())
{
  // Here the Dispose Will Be Called Automatically.
  // using requires the Object to implement 'IDispoasble'
}

Note – Even in the below code the Reosurce Object is created indirectly, the Dispose() will be called automatically,
          if the assignment is used in ‘using’ block as below.

class TestClass
    {
        public MyResource GetResource()
        {
            int x = 10;
            IntPtr ptr = new IntPtr(x);
            MyResource obj = new MyResource(ptr);
            return obj;
        }
    }
Usage – Implicit Approach

TestClass clsObject = new TestClass();
using (Resource theInstance1 = clsObject.GetResource())
{
  // Here also the Dispose Will Be Called Automatically. 
}



Why are we clearing both Managed & UnManaged both when the Dispose() is called explicitly by the consumer? Why not only UnManaged? i.e using MyDispose (true);

-          One reason is – In the Dispose() we are suppressing the Finalize/Destructor of the Resource class. Hence if we do not clear Managed resources then who will collect them.
-          Second - If a consumer calls IDisposable.Dispose(), then that consumer is indicating that all managed and unmanaged resources associated with that object should be cleaned up.

Why are we clearing only UnManaged when Destructor is called ? i.e using MyDispose (false);

-          If a destructor has been invoked, then all resources still need to be cleaned up. However, in this case, we know that the current DESTRUCTOR MUST HAVE BEEN CALLED BY THE GC and we should not attempt to access other managed objects because we can no longer be certain of their state. In this situation, the best we can do is clean up the known unmanaged resources, and Hope That any referenced managed objects also have destructors that will perform their own cleaning up.


-          Do not call Close or Dispose on a Connection, a DataReader, or any other managed object in the Finalize method of your class. In a finalizer, only release unmanaged resources that your class owns directly. If your class does not own any unmanaged resources, do not include a Finalize method in your class definition.




Check Class List that support Dispose() – Reference.
However for quick reference below objects support Dispose().

AsymmetricAlgorithm,BinaryReader ,BinaryWriter ,Brush ,CacheDependency ,Component ,ComponentDesigner ,Container ,Control ,CryptoAPITransform ,Cursor ,CustomLineCap ,DesignerTransaction ,EncoderParameter ,EncoderParameters ,EventHandlerList ,Font ,FontCollection ,FontFamily ,FromBase64Transform ,Graphics ,GraphicsPath ,GraphicsPathIterator ,HashAlgorithm ,HttpApplication ,Icon ,Image ,ImageAttributes,IsolatedStorageFile ,License ,LocalizationExtenderProvider ,ManagementObjectCollection ,MarshalByValueComponent ,Matrix ,MessageEnumerator ,MessageQueueEnumerator ,MessageQueueTransaction ,OdbcDataReader,OdbcTransaction ,OleDbDataReader ,OleDbTransaction ,OracleDataReader ,OracleTransaction ,PaintEventArgs ,Pen ,Region ,RegistryKey ,ResourceReader ,ResourceSet ,ResourceWriter ,ResXResourceReader ,ResXResourceWriter ,SearchResultCollection ,ServicedComponent ,Socket,SqlCeCommand ,SqlCeConnection ,SqlCeDataReader ,SqlCeEngine ,SqlCeRemoteDataAccess ,SqlCeReplication ,SqlCeTransaction ,SqlDataReader ,SqlTransaction ,Stream ,StringFormat ,SymmetricAlgorithm ,TcpClient ,TempFileCollection ,TemplateEditingVerb ,TextReader ,TextWriter ,Timer ,ToBase64Transform ,TraceListener ,UdpClient ,WaitHandle ,WebResponse

Why only these Objects support Dispose() and not others ??

The clue is these Objects mut have been using multiple Unmanaged resources internally (As in our example above). Now to clear all the referred unmanaged resources by these Objects, in one shot, Dispose is been supprted by these Objects.
The rest of the Objects must have not been using any Unmanaged resources internally i.e all the internally reference objects are Managed. Thus Dispose is not required to reclaim the memory as the GC can take care of the Managed Resources referenced by these Objects.

Is it Thread Safe –

This simplistic approach is not thread-safe and depends on the caller ensuring only one thread is calling the method concurrently.

Last Question – Why IDisposable is used to clear UnManaged Resources ??

-          In nut shell remember the fact that the GC does not take care of memory reclaimation for UnManagedResources. This is what individual component containing UnManaged resoures (like in our example) is required to handle.
-          Now to handle this, one can go for its own implentation. i.e In your application one can define thier own Interface like XDisposable and define a method, may be XDispose().
-          After this the way we implement IDisposable, use XDisposable and then implement the XDispose() in your class.
-          Once implemented use it the way you use IDisposable.

The only limitation would be – ‘Using’ block will not fire the XDispose() automatically.



public class MyResource : XDisposable
    {
        // Any Code
        public void XDispose()  // IDisposable Implementation
        {
            MyDispose (true);
            GC.SuppressFinalize(this);
        }

        private void MyDispose(bool thruDispose)
        {           
            // Code Here
        }

        ~MyResource()
        {
            MyDispose (false);
        }
    }
Usage – Explicit Approach

    Resource theInstance = null;
    try
    {
            theInstance = new Resource();
    }
    finally
    {
            if (theInstance != null)
            {
                theInstance.XDispose();  // Calling Explicity
            }
    }

Usage – Implicit Approach  - This will not work

using (Resource theInstance1 = new Resource())
{
  // Here the XDispose() Will Not Be Called Automatically.
 
}




Regards,
Arun Manglick



Pointers & Unsafe Myth

Hi,

 

This is about ‘Unsafe Code’.

 

-          C# is very good at hiding much of the basic memory management from the developer.

-          However, there are cases in which you will want direct access to memory. For example, you might want to access a function in an external (non-.NET) DLL that requires a pointer to be passed as a parameter (as many Windows API functions do), or possibly for Performance Reasons.

-          C#’s facilities the direct access to the contents of memory using – Pointers.

 

 

Pointers –

 

-          A pointer is simply a variable that stores the address of something else in the same way as a reference.

-          On the other hand using references in C# is also a type-safe pointer.

-          The difference is that C# does not allow you direct access to the address contained in a reference variable. With a reference, the variable is treated syntactically as if it stores the actual contents of the referent.

 

-          C# references prevent you from inadvertently doing something that corrupts the contents of memory.

-          With a pointer, on the other hand, the actual memory address is available to you. This gives you a lot of power to perform new kinds of operations.

 

However there are two main reasons for using pointers:

 

-          Backwards compatibility

 

§                     Despite all of the facilities provided by the .NET runtime, it is still possible to call native Windows API functions, and for some operations, this may be the only way to accomplish your task.

§                     These API functions are generally written in C and often require pointers as parameters.

§                     However, in many cases it is possible to write the DllImport declaration in a way that avoids use of pointers, for example, by using the System.IntPtr class.

 

-          Optimized Performance

 

§                     On those occasions where speed is of the utmost importance, Pointers Can Provide A Route To Optimized Performance.

§                     Provided you know what you are doing, you can ensure that data is accessed or manipulated in the most efficient way.

 

 

Pointer Hiccups –

 

-          Low-level memory access comes at a price. The syntax for using pointers is more complex than that for reference types and pointers are unquestionably more difficult to use correctly.

-          You need good programming skills and an excellent ability to think carefully and logically about what your code is doing in order to use pointers successfully.

-          If you are not careful, it is very easy to introduce subtle, difficult to find bugs into your program using pointers. For e.g.

§                     Overwrite other variables,

§                     Cause stack overflows,

§                     Access areas of memory that don’t store any variables, or

§                     Even overwrite information about your code that is needed by the .NET runtime, thereby crashing your program.

 

-          In addition, if you use pointers your code must be granted a high level of trust by the code access security mechanism or it will not be allowed to execute.

-          Under the default code access security policy, this is only possible if your code is running on the local machine.

-           If your code must be run from a remote location, such as the Internet, users must grant your code additional permissions for it to work.

 

 

Unsafe Block –

 

-          Due to the risks associated with pointers, C# only allows the use of pointers in blocks of code that you have specifically marked for this purpose using ‘unsafe’ keyword.

-          Otherwise it produces error while compiling.

-          Once you have any ‘unsafe’ code, the application will not compile in normal fashion. To compile either you have to use the /unsafe switch or check the checkbox which allows unsafe code in your application using ‘Project Properties’ dialog.

 

csc /unsafe MySource.cs

csc -unsafe MySource.cs

 

You can mark an Individual Method as being unsafe like this:

unsafe int GetSomeNumber()

{

// code that can use pointers

}

 

You can also mark an Entire Class Or Struct as unsafe, which means that all of its members are assumed to be unsafe:

unsafe class MyClass

{

// any method in this class can now use pointers

}

 

You can mark a Member as unsafe:

class MyClass

{

  unsafe int *pX; // declaration of a pointer field in a class

}

 

 

You can mark a Block Of Code within a method as unsafe:

void MyMethod()

{

// code that doesn’t use pointers

unsafe

{

// unsafe code that uses pointers here

}

// more ‘safe’ code that doesn’t use pointers

}

    

You cannot mark a local variable by itself as unsafe:

int MyMethod()

{

 unsafe int *pX; // WRONG

}

 

Hope this helps.

 

Regards,

Arun Manglick