2010-04-25 3 views
15

Предположим, что у меня есть следующий код:Выполняет ли выполнение инструкции C# try/finally?

private void UpdateDB(QuoteDataSet dataSet, Strint tableName) 
{ 
    using(SQLiteConnection conn = new SQLiteConnection(_connectionString)) 
    { 
     conn.Open(); 
     using (SQLiteTransaction transaction = conn.BeginTransaction()) 
     { 
      using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM " + tableName, conn)) 
      { 
       using (SQLiteDataAdapter sqliteAdapter = new SQLiteDataAdapter()) 
       { 
        sqliteAdapter.Update(dataSet, tableName); 
       } 
      } 
      transaction.Commit(); 
     } 
    } 
} 

C# документации говорится, что с using утверждением объекта в пределах будут захоронены, и я видел несколько мест, где он предположил, что нам не нужно для использования предложения try/finally.

Обычно я окружаю свои связи с помощью try/finally, и я всегда закрываю соединение в предложении finally. Учитывая приведенный выше код, разумно ли предположить, что соединение будет закрыто, если есть исключение?

+0

Подобно http://stackoverflow.com/questions/278902/ using-statement-vs-try-finally –

+5

Не ответ на ваш вопрос. Пожалуйста, прочитайте об атаках на SQL-инъекции. –

ответ

18

You are correct; the using statement compiles to a try/finally block.

Компилятор преобразует using(resource) statement; в следующий код:.

{ 
    ResourceType resource = expression; 
    try { 
     statement; 
    } 
    finally { 
     if (resource != null) ((IDisposable)resource).Dispose(); 
    } 
} 

(Актерский к IDisposable находится в случае ResourceType орудий IDisposable явно

+0

Что лучше всего выпустить ресурс, который не может быть создан при использовании инструкции или повторного использования или передается как параметр param? – bjan

+0

@bjan: Это зависит от ситуации. – SLaks

1

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

10

Да, вам либо нужно использовать оператор try/finally или using. Вам не нужны оба.

A using statement почти то же самое, что и try/finally, за исключением того, что в C# 3 вы не можете переназначить переменную внутри блока использования.

using (IDisposable d = foo()) 
{ 
    d = null; // Error: Cannot assign to 'd' because it is a 'using variable' 
} 

Раньше вы могли бы переназначить, но исходный объект будет по-прежнему быть утилизированы, а не вновь назначенный объект, и вы также можете получить это предупреждение при компиляции:

Возможно неправильное назначение на местном уровне «D», который является аргумент для использования или блокировки. Вызов Dispose или разблокировка произойдет по первоначальному значению локального.

+0

Что лучше всего выпускать ресурс, который нельзя создать в результате использования инструкции или повторно использовать или передаваться как параметр param? – bjan

6

Да, заявление using в значительной степени просто сокращено для блока try ... finally.

Например, этот код ...

using (MyDisposableType foo = new MyDisposableType()) 
{ 
    foo.DoSomething(); 
} 

... будет приравнивать к следующему ...

{ 
    MyDisposableType foo = new MyDisposableType(); 
    try 
    { 
     foo.DoSomething(); 
    } 
    finally 
    { 
     if (foo != null) 
      ((IDisposable)foo).Dispose(); 
    } 
} 
1

Использование() гарантирует, что элемент инстанцирован в пределах параметров будет удаляется независимо от того, что происходит внутри связанного кодового блока. Это включает в себя закрытие соединения с базой данных, предполагая, что SQLiteConnection корректно обрабатывает его.

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