2016-12-12 6 views
0

Вот мой код:Почему я должен использовать Dispose()?

public void InsertData() 
{ 
    using (SqlConnection connection = new SqlConnection(DBHelper.ConnectionString)) 
    { 
     using (SqlCommand command = new SqlCommand("Some Simple Insert Query", connection)) 
     { 
      connection.Open(); 
      command.ExecuteNonQuery(); 
     } 
    } 
} 

Но я нашел этот образец кода:

public void InsertData() 
{ 
    SqlConnection connection = new SqlConnection(DBHelper.ConnectionString); 
    connection.Open(); 
    SqlCommand command = new SqlCommand("Some Simple Insert Query", connection); 
    command.ExecuteNonQuery(); 

    command.Dispose(); 
    connection.Close(); 
    connection.Dispose(); 
} 

почему автор использовать

command.Dispose()

и

соединение.Dispose();

в своем коде?

+1

https://msdn.microsoft.com/en-us/library/yh598w02.aspx –

ответ

3

Вам не нужно использовать dispose в вашем примере, потому что используемый блок делает это за вас.

Смотрите здесь: using Statement (C# Reference)

+0

так "с помощью" блок не нужен какой-нибудь метод «Утилизация»? –

+0

Нет, они этого не делают. –

+1

Я бы сказал, что это oposite 'using' требует' Dispose', но вызывает его для вас. В этом разница. –

5

using может быть использован только на объектах, которые являются одноразовых (что, когда они реализуют интерфейс IDisposable). Это автоматически вызовет Dispose на этом экземпляре. Однако, в отличие от самого вызова, это условие using гарантирует, что Dispose также вызывается, когда возникает исключение в этом блоке. Так что безопаснее использовать этот подход.

Ваш первый пример эквивалентен следующему:

try 
{ 
    SqlConnection connection = new SqlConnection(DBHelper.ConnectionString); 
    connection.Open(); 
    SqlCommand command = new SqlCommand("Some Simple Insert Query", connection); 
    try 
    {    
     command.ExecuteNonQuery(); 
    } 
    finally 
    { 
     command.Dispose(); 
    } 
} 
finally 
{ 
    connection.Dispose(); 
} 
3

Он использует connection.Dispose();, потому что человек не имеет опыта и писать плохой код, который не является безопасным. Если выбрано исключение, соединение никогда не будет удалено из-за того, что он останется открытым до тех пор, пока GC не соберет соединение, возможно, минут или часов позже.

+0

GC никогда не будет закрывать его в любое время, поскольку это неуправляемый ресурс, который GC * can't * может обрабатывать вообще. Не избавление от ressource просто создает тупик, который закрывается только при перезагрузке. – HimBromBeere

+0

@HimBromBeere GC * может * очистить его в финализаторе. Это возможно *, что он никогда не очищается, но также возможно, что это будет. – Servy

3

В .Net IDisposable и метод Dispose используются для очистки неуправляемых ресурсов.

.Net отслеживает управляемые ресурсы, поэтому он может автоматически очищать их, но при этом им нужна помощь при работе с неуправляемыми ресурсами.

Выполняет задачи, связанные с приложением, связанные с освобождением, выпуском или сбросом неуправляемых ресурсов.

https://msdn.microsoft.com/en-us/library/system.idisposable.dispose(v=vs.110).aspx

используя оператор является способ автоматического вызова метода Dispose, когда вы закончите его использования.

Обеспечивает удобный синтаксис, который обеспечивает правильное использование объектов IDisposable.

Он даже вызывается, если вызывается исключение.

Оператор using гарантирует, что Dispose вызывается, даже если возникает исключение, когда вы вызываете методы на объекте. Вы можете добиться того же результата, поставив объект внутри блока try и затем вызывая Dispose в блоке finally; Фактически, это то, как оператор using преобразуется компилятором.

https://msdn.microsoft.com/en-us/library/yh598w02.aspx

код, который не используя используя операторы неверен.

Это будет работать большую часть времени, но если произойдет исключение, неуправляемые ресурсы в SqlConnection могут быть оставлены неочищенными.

Как правило, когда вы используете объект IDisposable, вы должны объявить его и создать его в операторе using.

3

using блок является просто синтаксический сахар для шаблона try/finallyDispose(). Все это объясняется в documentation.

Примечание вы можете также уменьшить отступы в коде:

using (SqlConnection connection = new SqlConnection(DBHelper.ConnectionString)) 
using (SqlCommand command = new SqlCommand("Some Simple Insert Query", connection)) 
{ 
    connection.Open(); 
    command.ExecuteNonQuery(); 
} 
4

Вы будете иметь ресурс утечки когда исключение было брошено:

public void InsertData() 
{ 
    SqlConnection connection = new SqlConnection(DBHelper.ConnectionString); 
    connection.Open(); 
    SqlCommand command = new SqlCommand("Some Simple Insert Query", connection); 
    command.ExecuteNonQuery(); // <- imagine that this throws exception 

    // and so these don't execute at all and you'll have two resources leaked: 
    // 1. Connection 
    // 2. Command 
    command.Dispose(); 
    connection.Close(); 
    connection.Dispose(); 
} 

Причины исключения могут отличаться:

1. Insert failed (e.g. invalid field value insertion) 
2. User doesn't have privelege required 
3. RDMBS Internal error 
... 

Вы можете эмулировать using с try .. finally который многословным:

public void InsertData() 
{ 
    SqlConnection connection = null; 

    try { 
     connection = new SqlConnection(DBHelper.ConnectionString); 
     connection.Open(); 

     SqlCommand command = null; 

     try { 
     command = new SqlCommand("Some Simple Insert Query", connection); 
     command.ExecuteNonQuery(); 
     } 
     finally { // rain or shine, dispose the resource (if it has been created) 
     if (command != null) 
      command.Dispose(); 
     } 
    } 
    finally { // rain or shine, dispose the resource (if it has been created) 
     if (connection != null) 
     connection.Dispose(); 
    } 
+0

thanks.i как этот код. –

 Смежные вопросы

  • Нет связанных вопросов^_^