Don't forget to call EndXxx() if initialized an asynchronous call via BeginXxx(), otherwise there will be resource leaks. I did forget to do this in post: [Multi-Threading] Syncing between Threads by SynchronizationContext .
EndXxx() usually should be called before you want to get the result of the asynchronous operation. You can call it right after BeginXxx(), or when you get noticed about the completion of the asynchronous operation. But remember, you should call it only for one time. If you call it the second time, the behaviour are not predicatible since resources have been released during the first call to EndXxx().
Monday, September 1, 2008
Sunday, August 31, 2008
How to Avoid Duplicated Initialization of Fields
It is said in Jeff's book that initialization work of a field together with its definition will be done in ctors. If you have several ctors, the field will be initialized in these ctors seperately. See following example:
    public partial class Window1 : Window
   {
       public class InnerObject
       {
           public InnerObject()
           {
               Debug.WriteLine("InnerObject() ctor.");
           }
       }
       public class Foo
       {
           private int field = 99;
           private InnerObject innerObject = new InnerObject();
           public Foo()
           {
           }
           public Foo(int a)
           {
           }
       }
       public Window1()
       {
           InitializeComponent();
           Foo foo1 = new Foo();
           Foo foo2 = new Foo(12);
       }
   }
.method public hidebysig specialname rtspecialname
       instance void  .ctor(int32 a) cil managed
{
 // Code size       29 (0x1d)
 .maxstack  8
 IL_0000:  ldarg.0
 IL_0001:  ldc.i4.s   99
 IL_0003:  stfld      int32 FieldInitialization.Window1/Foo::'field'
 IL_0008:  ldarg.0
 IL_0009:  newobj     instance void FieldInitialization.Window1/InnerObject::.ctor()
 IL_000e:  stfld      class FieldInitialization.Window1/InnerObject FieldInitialization.Window1/Foo::innerObject
 IL_0013:  ldarg.0
 IL_0014:  call       instance void [mscorlib]System.Object::.ctor()
 IL_0019:  nop
 IL_001a:  nop
 IL_001b:  nop
 IL_001c:  ret
} // end of method Foo::.ctor
.method public hidebysig specialname rtspecialname
       instance void  .ctor() cil managed
{
 // Code size       29 (0x1d)
 .maxstack  8
 IL_0000:  ldarg.0
 IL_0001:  ldc.i4.s   99
 IL_0003:  stfld      int32 FieldInitialization.Window1/Foo::'field'
 IL_0008:  ldarg.0
 IL_0009:  newobj     instance void FieldInitialization.Window1/InnerObject::.ctor()
 IL_000e:  stfld      class FieldInitialization.Window1/InnerObject FieldInitialization.Window1/Foo::innerObject
 IL_0013:  ldarg.0
 IL_0014:  call       instance void [mscorlib]System.Object::.ctor()
 IL_0019:  nop
 IL_001a:  nop
 IL_001b:  nop
 IL_001c:  ret
} // end of method Foo::.ctor
        public class Foo
       {
           private int field = 99;
           private InnerObject innerObject = new InnerObject();
           public Foo()
           {
           }
           public Foo(int a) : this()
           {
           }
       }
.method public hidebysig specialname rtspecialname
       instance void  .ctor(int32 a) cil managed
{
 // Code size       10 (0xa)
 .maxstack  8
 IL_0000:  ldarg.0
 IL_0001:  call       instance void FieldInitialization.Window1/Foo::.ctor()
 IL_0006:  nop
 IL_0007:  nop
 IL_0008:  nop
 IL_0009:  ret
} // end of method Foo::.ctor
.method public hidebysig specialname rtspecialname
       instance void  .ctor() cil managed
{
 // Code size       29 (0x1d)
 .maxstack  8
 IL_0000:  ldarg.0
 IL_0001:  ldc.i4.s   99
 IL_0003:  stfld      int32 FieldInitialization.Window1/Foo::'field'
 IL_0008:  ldarg.0
 IL_0009:  newobj     instance void FieldInitialization.Window1/InnerObject::.ctor()
 IL_000e:  stfld      class FieldInitialization.Window1/InnerObject FieldInitialization.Window1/Foo::innerObject
 IL_0013:  ldarg.0
 IL_0014:  call       instance void [mscorlib]System.Object::.ctor()
 IL_0019:  nop
 IL_001a:  nop
 IL_001b:  nop
 IL_001c:  ret
} // end of method Foo::.ctor
As you can see initialization code in Foo(int a) is gone. C# compiler did the optimization. I think, it's the better way of initializing fields, though Jeff suggest to do initialization expilicitly in default ctor.
But, I have a question, can we rely on this optimization behavor of C# compiler?
Subscribe to:
Comments (Atom)
 
