GC не заботится ни о чем, кроме памяти, поэтому, если у вас много памяти и вы не занимаете ее много, может пройти очень много времени, пока она не выполнит GC. В течение всего этого времени неуправляемые ресурсы, такие как сетевые соединения, файловые дескрипторы, соединения с базой данных, графические дескрипторы и т. Д., Остаются связанными объектами, ожидающими получения GC. Это может привести к тому, что вам не хватит этих ресурсов, и сборщик мусора не заметит, потому что он не контролирует неуправляемые ресурсы.
Таким образом, если вы поместите свой код в цикл и продолжаете вызывать его, не вызывая Dispose, вы можете обнаружить, что он быстро ухудшает производительность (процессы борются за ограниченные ресурсы) или дает исключение из-за нехватки неуправляемых ресурсов. Это зависит от контекста того, как он вызывается и как вы создаете другие связанные объекты. Вместо того чтобы анализировать каждую ситуацию, всегда безопаснее вызывать Dispose, как только вы закончите работу с экземпляром.
Это правда, что в конечном итоге Dispose будет вызываться GC для объекта, который вышел из области видимости / на него больше не ссылаются, но это является неопределенным. Будучи недетерминированным, вы можете увидеть разные результаты в том, как скоро ресурсы будут свободны при тестировании по сравнению с производством, и привести к случайным исключениям из-за невозможности выделить ресурсы, когда они закончатся. Если бы вы могли выбирать между непротиворечивым детерминированным поведением вашего приложения и индетерминированным, вы, вероятно, захотите детерминированный, если только вы не пытаетесь запутать своих тестеров.