Привет всем.
Вот пример реализации конструктора класса объекта, который управляет ресурсом в виде блока памяти.
// System.Data.OleDb.PropertyIDSet
internal PropertyIDSet(Guid propertySet, int propertyID) : base(PropertyIDSet.PropertyIDSetAndValueSize)
{
this._count = 1;
IntPtr intPtr = ADP.IntPtrOffset(this.handle, PropertyIDSet.PropertyIDSetSize);
Marshal.WriteIntPtr(this.handle, 0, intPtr);
Marshal.WriteInt32(this.handle, ADP.PtrSize, 1);
intPtr = ADP.IntPtrOffset(this.handle, ODB.OffsetOf_tagDBPROPIDSET_PropertySet);
Marshal.StructureToPtr(propertySet, intPtr, false);
Marshal.WriteInt32(this.handle, PropertyIDSet.PropertyIDSetSize, propertyID);
}
В данном коде интересна последняя строчка. В ней (грубо говоря)
1. читается значение
this.handle (это адрес блока памяти) и помещается в стек
2. вызывается Marshal.WriteInt32.
Формально, если этот конструктор вызывается из кода вида
new PropertyIDSet(new Guid(),1);
То сборщик мусора между п1 и п2 вполне может решить, что конструируемый объект (this) больше не достижим, и инициирует его освобождение (то есть — освобождение блока памяти ресурса). И, в результате, Marshal.WriteInt32 тупо испортит память?
Или то, что
new (формально) передает this в конструктор, а потом возвращает его (this) вызывающей стороне, удерживает GC от уничтожения этого объекта?
Эта мысль пришла в голову во время написания этого сообщения
----
Вообщем — может ли GC
изничтожить освободить объект, конструктор которого еще не закончил работу?
тут я немного подумал еще, и понял — это же можно проверить самому
Смелый эксперимент (потомка советского инженера) показывает — да запросто
| Скрытый текст |
| using System;
class A
{
static void RunGC()
{
// Производим сборку мусора.
Console.WriteLine("Run GC");
GC.Collect();
GC.WaitForPendingFinalizers();
}
public A()
{
Console.WriteLine("A - in");
RunGC();
Console.WriteLine("A - out");
}//if
~A() { Console.WriteLine("~A();"); }
static void Main()
{
Console.WriteLine("Main - in");
new A();
Console.WriteLine("Main - point #1");
RunGC();
Console.WriteLine("Main - exit");
}//Main
}//class A
Main - in
A - in
Run GC
~A();
A - out
Main - point #1
Run GC
Main - exit
Для продолжения нажмите любую клавишу . . .
|
| |
-- Пользователи не приняли программу. Всех пришлось уничтожить. --