Domanda

Ho una classe (diciamo MyClass) che usa (ha come un campo privato) un oggetto TcpClient. MyClass implementa IDisposable chiamata TcpClient.Close nel metodo Dispose.

La mia domanda è dovrebbe MyClass anche attuare un finalizzatore di chiamare Dispose(bool Disposing) per liberare le risorse non gestite TcpClient’s nel caso in cui MyClass.Dispose non è chiamato dal codice chiamante?

Grazie

È stato utile?

Soluzione

No non si dovrebbe.

A causa non si dovrebbe mai chiamare un metodo su un altro oggetto in un finalizzatore , che avrebbe potuto essere finalizzato prima l'oggetto.

Il finalizzatore del TcpClient sarà chiamato dal garbage collector, quindi lo lasciò fare.

Il modello in Dispose è:

protected virtual void Dispose(bool disposing)
{
   if (disposing)
   { 
      // dispose managed resources (here your TcpClient)
   }

   // dispose your unmanaged resources 
   // handles etc using static interop methods.
}

Altri suggerimenti

No non si dovrebbe.

Da questo ottimo post:

  

La finalizzazione è fondamentalmente   diverso da finire un oggetto di   tutta la vita. Da un punto di correttezza   vista, non c'è nessun ordinamento tra   finalizzatori (al di fuori di un caso speciale   per finalizzatori critici), quindi se si   avere due oggetti che il GC pensa   sono morti allo stesso tempo, non si può   prevedere quali finalizzatore completerà   primo. Questo significa che non si può avere un   finalizzatore che interagisce con qualsiasi   oggetti finalizable memorizzati in caso   variabili.

Questa è la mia implementazione di riferimento del modello finalizzare / usa e getta con i commenti che spiega quando usare cosa:

/// <summary>
    /// Example of how to implement the dispose pattern.
    /// </summary>
    public class PerfectDisposableClass : IDisposable
    {
        /// <summary>
        /// Type constructor.
        /// </summary>
        public PerfectDisposableClass()
        {
            Console.WriteLine( "Constructing" );    
        }

        /// <summary>
        /// Dispose method, disposes resources and suppresses finalization.
        /// </summary>
        public void Dispose()
        {
            Dispose( true );
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Disposes resources used by class.
        /// </summary>
        /// <param name="disposing">
        /// True if called from user code, false if called from finalizer.
        /// When true will also call dispose for any managed objects.
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            Console.WriteLine( "Dispose(bool disposing) called, disposing = {0}", disposing );

            if (disposing)
            {
                // Call dispose here for any managed objects (use lock if thread safety required), e.g.
                // 
                // if( myManagedObject != null )
                // {
                //     myManagedObject.Dispose();
                //     myManagedObject = null;
                //  }
            }
        }

        /// <summary>
        /// Called by the finalizer.  Note that if <see cref="Dispose()"/> has been called then finalization will 
        /// have been suspended and therefore never called.
        /// </summary>
        /// <remarks>
        /// This is a safety net to ensure that our resources (managed and unmanaged) are cleaned up after usage as
        /// we can guarantee that the finalizer will be called at some point providing <see cref="Dispose()"/> is
        /// not called.
        /// Adding a finalizer, however, IS EXPENSIVE.  So only add if using unmanaged resources (and even then try
        /// and avoid a finalizer by using <see cref="SafeHandle"/>).
        /// </remarks>
        ~PerfectDisposableClass()
        {
            Dispose(false);
        }
    }

No, non c'è bisogno di. TcpClient è una classe wrapper presa gestito e lì viene gestita come dovrebbe essere smaltito. Quello che hai fatto è sufficiente.

Si deve - Microsoft consiglia addirittura .

Basta ricordare che il codice cintura e bretelle non viene mai chiamato in ufficio alle 2:00 AM:)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top