Когда я запускаю его, отключает :
Scroll()
GetInts connected
yield 99
99
...snip...
yield 90
90
Scroll() completed
DataSource Disconnected
Program End
Обратите внимание, что будет отключать сам , если вы читали до конца данных; однако вы запрашиваете 100 дюймов и просматриваете 10 из них; насколько бы ни был важен итератор, вы оставили его на 10%. Если вы исчерпали блок итератора, он очищает любые using
и т. д .; если вы не исчерпали его, он должен быть явно уничтожен. Вы можете проиллюстрировать это, изменив его на GetInts(5)
(оставив все остальные коды такими же):
Scroll()
GetInts connected
yield 4
4
yield 3
3
yield 2
2
yield 1
1
yield 0
0
DataSource Disconnected
GetInts disconnected
Scroll() completed
Program End
Причина, по которой он не показывает «GetInts отключен» в противном случае, заключается в том, что ... он никогда не доберется до тех пор, пока вы не исчерпаете его! Вот что говорит ваш код: «печать подключена; выдача i
элементов; печать отключена» - он не будет печатать отключенный, если он сначала не выполнил все операции. Если вы используете finally
(снова используя GetInts(100)
), то это изменится:
static IEnumerable<int> GetInts(int i)
{
Console.WriteLine("GetInts connected");
try
{
using (var ds = new DataSourceWrapper())
{
while (i-- != 0)
{
Console.WriteLine("yield {0}", i);
yield return i;
}
}
}
finally
{
// not called!
Console.WriteLine("GetInts disconnected");
}
}
Тогда это работает:
...
yield 90
90
Scroll() completed
DataSource Disconnected
GetInts disconnected
Program End
По сути, finally
отображается в Dispose()
итератора.
Кроме того, _mIter
равно IEnumerator<T>
; он явно реализует IDisposable
, и вы несете ответственность за вызов Dispose()
в какой-то момент. Сделай это, и все будет работать. Даже с IEnumerator
(не универсальным, не явно IDisposable
) вы должны следовать тому же подходу, что и компилятор, и проверить , если перечислитель IDisposable
, и вызвать Dispose()
соответственно.
Поскольку вы не используете данные в одном блоке, вы не можете использовать using
, но вы все равно должны их утилизировать. Это может означать, что ваш агрегат типа IDisposable
и передача вызова. Кроме того, вы можете явно удалить и освободить перечислитель, когда достигнете конца. Я не могу изменить ваш код, чтобы проиллюстрировать это, так как это не имеет смысла для static
данных, но я надеюсь, что перечислитель не будет static
в реальном коде в любом случае.