2015-06-22 3 views
0

Вот где .NET начинает делать свою голову Рассмотрим следующий сценарий:.Что происходит с объектами DataRow, когда Dispose вызывается в DataTable?

  1. У меня есть DataTable объект, содержащий ряд DataRow объектов
  2. добавить некоторые из DataRow объектов в массив
  3. Я звоню Dispose на DataTable.

Какие гарантии у меня есть, что вызов Dispose на DataTable не ухудшала DataRow объектов (которые, по ссылке, будет влиять на тех, которые добавлены в массив)?

MS documentation - это нулевая помощь в этом случае.

EDIT: До сих пор люди пропустили точку целиком. IDisposable Объекты означают, которые должны быть удалены как можно скорее. В течение обычного дня мой код будет создавать тысячи объектов DataTable. Ни в коем случае я не оставляю тех, кто не размещен, если они реализуют IDispoable.

НО, мне нужно несколько DataRow объектов, чтобы остаться в живых, потому что это то, что ожидает, что моя третья сторона бинарная (который я не имею никакого контроля над). И мне нужно, чтобы они остались в живых для значительно длиннее, чем DataTable объектов.

Все что мне нужно, это авторитетная информация, которая описывает, что Dispose на DataTable на самом деле делает. Похоже, что указанной информации не существует, поэтому я прошу здесь о помощи. У кого-то может быть ссылка или документация, которую я упускал из виду, что отвечает на мои потребности.

EDIT 2: я испытал, как Blam предложил, включая добавление GC.Collect + получение бонуса GC.WaitForPendingFinalizers + еще один GC.Collect после размещени DataTable. DataRows кажутся прекрасными, все еще живыми и доступными. Это положительно, но увы не авторитетное достаточно включить в производственном коде :-(

+4

Что вы подразумеваете под «компромиссом»? Если вы все еще хотите использовать объекты DataRow, то почему вы удаляете «DataTable», который содержит их в первую очередь? Устранить что-то нужно только тогда, когда вы больше не пользуетесь им. Если у вас есть дальнейшее использование для «DataTable», тогда не используйте его в первую очередь. – jmcilhinney

+1

Что вы получаете от сохранения DataRows в массиве? – Tarik

+1

@Tarik Я получаю совместимость с методом (сторонний двоичный файл), который ожидает DataRows в массиве ;-) – misha256

ответ

-2

таблица данных никогда не будет сборки мусора. Dotnet будет компилировать код, чтобы сохранить эту сетку, пока массив больше не ссылается указанная строкой. Типичный сценарий, который я видел, заключается в том, что до тех пор, пока родительский объект, создавший сетку и массив, не будет удален, сетка будет оставаться в процессе, отмеченном для удаления, но никогда не будет собираться мусором, поскольку он имеет ожидающую ссылку.

В другими словами, избегайте этого, потому что обычно он не будет правильно мусор собирать сетку, пока приложение не будет закрыто.

Если это неуправляемый код, он должен взорваться при первой ссылке после удаления.

3

DataTable не переустанавливает MarshalByValueComponent.Dispose, и этот метод на самом деле не делает само по себе. Таким образом, вызов DataTable.Dispose ничего не делает для таблицы или содержащихся в ней данных.Интересно, что DataTable даже заходит так далеко, чтобы подавить финализацию в конструкторе, потому что it doesn't hold unmanaged resources.

Теперь, если вы посмотрите на определение для DataRow, вы заметите, что он не реализует IDisposable (или что-нибудь в этом отношении), не имеет финализатора и т. Д. Однако он имеет зависимость от таблицы (которую он получает через DataRowBuilder, переданный в конструкторе). Обычно в такой ситуации вы никогда не хотите вызывать dispose на собственном объекте до тех пор, пока его больше не понадобится, поскольку может привести к тому, что побочные эффекты от этой родительской ссылки уже удалены.

Однако в этом случае вызов dispose фактически не делает ничего, и это не имеет значения в любом случае. Фактически, вы вызываете Dispose как преждевременную оптимизацию, которая мало или вообще не действует, поэтому она излишняя. Ваш DataRow s и данные, которые они содержат, не будут затронуты вызовом dispose в таблице.

(К сожалению, но не жаль пример C#, а не VB.NET, но нет никакой разницы между ними в данном примере, за исключением того, один уродливее, чем другой; р)

var table = new DataTable(); 

table.RowDeleting += (sender, e) => { 
    Console.WriteLine("Deleting"); 
}; 
table.Clear(); 
table.Columns.Add("Foo"); 
table.Columns.Add("Bar"); 

var row = table.NewRow(); 
row["Foo"] = "Hello"; 
row["Bar"] = "World"; 
table.Rows.Add(row); 

table.Dispose(); // "Dispose call! We've got a Dispose call here!" 

row.Delete(); // "See? No one cares." 

Я дон Не знаю, что составляет достаточно авторитетным для производственного кода, но там вы идете.

+1

Увлекательный, спасибо. Вы определили зависимость между 'DataRows' и родительским' DataTable'. Этого достаточно для того, чтобы я отступил и сказал * «вы знаете что нам нужно глубоко скопировать эти строки, чтобы не было никакой зависимости. Несмотря на то, что ваши исследования показывают, что в моем случае все будет хорошо работать, нет гарантии, что MS не будет обновлять фреймворк в будущем и нарушить это недокументированное поведение. хороший конструктивный ответ. – misha256

+0

@ misha256 Если они меняют его, это будет довольно существенное изменение в этой функции. Этот дизайн также не изменился очень долго (если когда-либо), поэтому я бы сказал, что он довольно стабилен. Конечно, вы свободны делать то, что хотите, но я бы не стал беспокоиться. – HackedByChinese

Смежные вопросы