Должен реализовать финализатор на классе, который использует TcpClient?

Я считаю, что этот сценарий может помочь вам:

DECLARE @Query TABLE (SchemaName    VARCHAR(100)
                    ,TableName  VARCHAR(100)
                    ,ColumnName VARCHAR(1000)
                    )
INSERT INTO @Query
SELECT A.TABLE_SCHEMA,A.TABLE_NAME,' MAX(CASE Charindex(''.'',' + QUOTENAME(COLUMN_NAME) + ') 
                                        WHEN 0 THEN 0 
                                        ELSE Len (Cast(Cast(Reverse(CONVERT(VARCHAR(50), ' + QUOTENAME(COLUMN_NAME) + ', 128) ) AS FLOAT) AS BIGINT)) 
                                        END) AS ['+COLUMN_NAME+'_MAX_LENGTH]'
FROM INFORMATION_SCHEMA.COLUMNS A
INNER JOIN INFORMATION_SCHEMA.TABLES B
ON A.TABLE_NAME = B.TABLE_NAME
WHERE TABLE_TYPE = 'BASE TABLE'
AND DATA_TYPE = 'FLOAT'

SELECT 'SELECT '+
        STUFF((
            SELECT ',' + ColumnName
            FROM @Query Q2
            WHERE Q1.SchemaName=q2.SchemaName AND  Q1.TableName=q2.TableName
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)')
            , 1, 2, '')
            +' FROM '+Q1.SchemaName+'.'+Q1.TableName
FROM 
(SELECT DISTINCT SchemaName,TableName FROM @Query) Q1
5
задан Andrew Hare 12 February 2009 в 15:32
поделиться

4 ответа

Нет Вы не были должны.

Поскольку Вы никогда не должны называть метод на другом объекте в финализаторе, он, возможно, был завершен перед Вашим объектом.

Финализатор Вашего TcpClient назовет сборщик "мусора", таким образом позвольте ему сделать.

Шаблон в Располагает:

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

   // dispose your unmanaged resources 
   // handles etc using static interop methods.
}
4
ответ дан 14 December 2019 в 09:01
поделиться

Нет Вы не были должны.

Из этого превосходного сообщения:

Завершение существенно отличается от окончания времени жизни объекта. С точки зрения правильности нет никакого упорядочивания между финализаторами (за пределами особого случая для критических финализаторов), поэтому если у Вас есть два объекта, что GC думает, мертвы одновременно, Вы не можете предсказать, какой финализатор завершится сначала. Это означает, что у Вас не может быть финализатора, который взаимодействует с любыми finalizable объектами, хранившими в переменных экземпляра.

Это - моя ссылочная реализация доступного/завершенного шаблона с комментариями, объясняющими, когда использовать что:

/// <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);
        }
    }
2
ответ дан 14 December 2019 в 09:01
поделиться

Нет Вы не имеете к. TcpClient является классом обертки вокруг неуправляемого сокета, и там для него управляется путем, он должен быть расположен. То, что Вы сделали, достаточно.

1
ответ дан 14 December 2019 в 09:01
поделиться

Да Вы должны - Microsoft даже рекомендует это.

Просто помните, что код пояса-и-подтяжек никогда не звонил Вам в офис в 2:00 :)

0
ответ дан 14 December 2019 в 09:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: