Qual é o propósito da instrução using?
-
24-12-2019 - |
Pergunta
Com base no que está escrito neste página da Internet, e se bem entendi, o using
declaração funciona como um try/finally
, então posso esperar erroneamente que, se ocorrer uma exceção em um using
declaração, ela não deve travar o programa.
No entanto, quando o DownloadString
método, mostrado no exemplo abaixo, lança um WebException
, o programa falha.
using (WebClient client = new WebClient())
{
string response = client.DownloadString(url);
// ...
}
Isto é normal, uma vez que o using
declaração não funciona como uma try/catch/finally
, então, na verdade, nenhuma exceção será tratada.Mas então me pergunto qual é o propósito do using
declaração.
ATUALIZAR... Com base nas respostas abaixo, acrescento as seguintes considerações.Basicamente, se eu precisar lidar com uma exceção, as possíveis soluções poderiam ser as seguintes.
- Coloque o
using
declaração dentro de umtry/catch
bloquear. - Coloque apenas o
DonwloadString
método dentro de umtry/catch
bloquear. - Escreva manualmente um bloco try/catch/finalmente como no exemplo de código a seguir.
Código de exemplo para a terceira solução.
WebClient client = new WebClient();
try
{
string response = client.DownloadString(url);
// ...
}
catch(Exception ex)
{
// handle (or ignore) the exception
}
finally
{
if (client != null)
client.Dispose();
}
Solução
se bem entendi, a instrução using funciona como uma tentativa/finalmente
Correto.
então, eu esperaria que, se ocorresse uma exceção em uma instrução using, ela não travasse o programa.
Incorreta.
Nenhum try/finally
nem using
instruções engolem exceções - se você não capturar a exceção, ela se propagará.Se não for detectado, geralmente encerrará o processo.(Existem alguns casos em que isso não acontece, com base em qual thread está inserido e como o CLR está configurado, mas isso é uma questão diferente.)
Mas então me pergunto qual é o propósito da instrução using.
Para simplificar a escrita de código que precisa descartar recursos.Isso é tudo.Se não tivéssemos using
declarações, teríamos uma muito de try
/finally
blocos que acabaram de ser chamados Dispose
...e isso seria consideravelmente mais feio.(Já estive lá, fiz isso - isso era Java até o Java 7 introduzir a instrução try-with-resources.)
Outras dicas
A using
declaração não faz com que todas as exceções desapareçam magicamente, apenas significa que o IDisposable.Dispose
método é chamado corretamente no client
objeto se ocorrer.Isto é importante para garantir que quaisquer recursos não gerenciados sejam liberados.
Ele irá relançar quaisquer exceções que ocorrerem e você ainda terá que lidar com elas em seu próprio código.
Consulte a descrição do MSDN de using
declaração
Em suma, usar garante que .Dispose()
é chamado mesmo se ocorrer uma exceção.No entanto, isso não impede a exceção de fazer seu trabalho.
A instrução using NÃO tem um problema, apenas um final e, portanto, dispõe do recurso para você.Se a instrução using capturasse todas as exceções e continuasse em execução, seria um grande obstáculo para a depuração.
É simplesmente mais fácil e rápido de usar e ler
Veja por si mesmo
var myVar = null
try
{
my = new Object();
//Do stuff
}
finally
{
if(myVar != null)
myVar.Dispose()
}
contra
using(var myVar = new Object())
{
//Do stuff
}
É simplesmente para garantir que Descartar é chamado nesse objeto.O usando não faça nenhum tratamento de exceção, pois o try/finally também não