[ Pobierz całość w formacie PDF ]
.But the outputtells a different story:Resource[0] ConstructedResource[1] ConstructedResource[2] ConstructedResource[3] ConstructedResource[4] ConstructedResource[5] ConstructedResource[6] ConstructedResource[7] ConstructedResource[8] ConstructedResource[9] ConstructedValuable resources used and discarded10 seconds later.No resources availableThings are awry!Resource[9] DestructedResource[8] DestructedResource[7] DestructedResource[6] DestructedResource[5] DestructedResource[4] DestructedResource[3] DestructedResource[2] DestructedResource[1] DestructedResource[0] DestructedEven after ten seconds (an eternity in computing time), no id’s are availableand the final attempt to create a ValuableResource fails.Interestingly, theMain() exits immediately after the “No resources available!” message iswritten.In this case, the CLR did do a garbage collection as the programexited and the ~ValuableResource() destructors got called.In this case, theyhappen to be deleted in the reverse order of their creation, but the order ofdestruction of resources is yet another “absolutely not guaranteed”characteristic of garbage collection.Worse, this is the output if one presses Ctl-C during the pause:Resource[0] ConstructedResource[1] ConstructedResource[2] ConstructedResource[3] ConstructedResource[4] ConstructedResource[5] ConstructedResource[6] ConstructedResource[7] ConstructedResource[8] ConstructedResource[9] ConstructedValuable resources used and discarded^CD:\tic\chap4>That’s it.No cleanup.If the valuable resources were, say, network sockets ordatabase connections or files or, well, anything that actually had any value,they’d be lost until you reboot (or some other process manages to restore theirstate by brute force, as can happen with files).//:c04:ValuableResource2.csusing System;using System.Threading;class ValuableResource{static int idCounter;static int MAX_RESOURCES = 10;static int INVALID_ID = -1;int id;ValuableResource(){if(idCounter == MAX_RESOURCES){System.Console.WriteLine("No resources available");id = INVALID_ID;}else{id = idCounter++;System.Console.WriteLine("Resource[{0}] Constructed", id);}}void Dispose(){idCounter--;System.Console.WriteLine("Resource[{0}] Destructed", id );if(id == INVALID_ID){System.Console.WriteLine("Things are awry!");}GC.SuppressFinalize(this);}~ValuableResource(){this.Dispose();}public static void Main(){useValuableResources();System.Console.WriteLine("Valuable resources used and discarded");Thread.Sleep(10000);System.Console.WriteLine("10 seconds later.");//This _is_ fineValuableResource vr = new ValuableResource();}static void useValuableResources(){for(int i = 0; i < MAX_RESOURCES; i++){ValuableResource vr = new ValuableResource();vr.Dispose();}}}///:~We’ve moved the code that was previously in the destructor into a method calledDispose().Additionally, we’ve added the line:GC.SuppressFinalize(this);Which tells the Garbage Collector (the GC object) not to call the destructorduring garbage collection.We’ve kept the destructor, but it does nothing butcall Dispose().In this case, the destructor is just a safety-net.It remainsour responsibility to explicitly call Dispose(), but if we don’t and it sohappens that the garbage collector gets first up, then our bacon is pulled outof the fire.Some argue this is worse than useless -- a method which isn’tguaranteed to be called but which performs a critical function.When ValuableResources2 is run, not only are there no problems with running outof resources, the idCounter never gets above 0!Destructors, Dispose(), and the using keywordWhat follows is confusing.We’ve talked about the only valid use of thedestructor being the guarantee that a valuable resource that exists as aninstance variable will be cleaned up.The C# language has a way to guaranteethat a special cleanup method is called, even if something unusual happens [ Pobierz caÅ‚ość w formacie PDF ]

  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • listy-do-eda.opx.pl