ProgrammationDéveloppeur .NET (desktop/web)

Comment le motif 'Dispose' (IDisposable) est-il implémenté en Visual Basic, pourquoi est-il important de l'utiliser et quelles sont les subtilités de la gestion des ressources ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

En Visual Basic, l'implémentation de l'interface IDisposable (motif Dispose) permet de libérer correctement les ressources (par exemple, les fichiers, les connexions à la base de données, les objets graphiques), qui ne sont pas gérées par le ramasse-miettes.

Une implémentation typique est la suivante :

Public Class FileManager Implements IDisposable Private fileStream As FileStream Private disposed As Boolean = False Public Sub New(path As String) fileStream = New FileStream(path, FileMode.Open) End Sub Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub Protected Overridable Sub Dispose(disposing As Boolean) If Not disposed Then If disposing AndAlso fileStream IsNot Nothing Then fileStream.Dispose() End If disposed = True End If End Sub Protected Overrides Sub Finalize() Dispose(False) MyBase.Finalize() End Sub End Class

Important : Utilisez la structure Using ... End Using — cela garantit l'appel automatique de Dispose :

Using manager As New FileManager("data.txt") ' opérations avec le fichier End Using

Subtilités :

  • Si votre classe possède des ressources, implémentez toujours IDisposable.
  • Si la classe est héritée, le motif doit être protégé et virtuel (Overridable), afin que les héritiers puissent ajouter le nettoyage de leurs ressources.
  • N'oubliez pas d'appeler GC.SuppressFinalize(this/me) — cela évite les appels de nettoyage en double.

Question piège.

Question : "Pourquoi est-il nécessaire d'appeler GC.SuppressFinalize(Me) dans la méthode Dispose ?"

Réponse correcte : Cela informe le ramasse-miettes qu'il n'est pas nécessaire d'appeler le finaliseur (Finalizer), car les ressources ont déjà été nettoyées manuellement via Dispose. Sans cela, le finaliseur s'exécutera inutilement, ce qui réduira les performances et peut entraîner un nettoyage en double.

Exemples d'erreurs réelles dues à la méconnaissance des subtilités du sujet.


Histoire

Dans un logiciel bancaire, IDisposable a été mal implémenté — ils ont oublié d'appeler Dispose sur la base de données, ce qui a entraîné des fuites de connexions. En moyenne, l'application "gelait" après 2–3 jours de fonctionnement continu.


Histoire

Dans un service médical, Dispose a été mal implémenté (missing "disposed" flag). La méthode Dispose était appelée plusieurs fois de suite, ce qui entraînait des tentatives de libération répétée d'une même ressource et provoquait des exceptions.


Histoire

Dans un éditeur graphique, ils ont oublié d'appeler GC.SuppressFinalize(Me). Le finaliseur s'exécutait même après Dispose, entraînant un double nettoyage des ressources et une instabilité (violation d'accès).