C # 2008
Estou trabalhando nisso há algum tempo e ainda estou confuso sobre o uso dos métodos finalize e descarte no código. Minhas perguntas estão abaixo:
Eu sei que precisamos apenas de um finalizador enquanto dispomos de recursos não gerenciados. No entanto, se houver recursos gerenciados que fazem chamadas para recursos não gerenciados, ainda seria necessário implementar um finalizador?
No entanto, se eu desenvolver uma classe que não use nenhum recurso não gerenciado - direta ou indiretamente, devo implementar o
IDisposable
para permitir que os clientes dessa classe usem a 'declaração de uso'?Seria viável implementar IDisposable apenas para permitir que os clientes de sua classe usassem a instrução using?
using(myClass objClass = new myClass()) { // Do stuff here }
Desenvolvi este código simples abaixo para demonstrar o uso Finalizar / descartar:
public class NoGateway : IDisposable { private WebClient wc = null; public NoGateway() { wc = new WebClient(); wc.DownloadStringCompleted += wc_DownloadStringCompleted; } // Start the Async call to find if NoGateway is true or false public void NoGatewayStatus() { // Start the Async's download // Do other work here wc.DownloadStringAsync(new Uri(www.xxxx.xxx)); } private void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { // Do work here } // Dispose of the NoGateway object public void Dispose() { wc.DownloadStringCompleted -= wc_DownloadStringCompleted; wc.Dispose(); GC.SuppressFinalize(this); } }
Pergunta sobre o código fonte:
Aqui eu não adicionei o finalizador, e normalmente o finalizador será chamado pelo GC, e o finalizador chamará Dispose. Como não tenho o finalizador, quando chamo o método Dispose? É o cliente da classe que precisa chamá-lo?
Portanto, minha classe no exemplo é chamada NoGateway e o cliente pode usar e descartar a classe assim:
using(NoGateway objNoGateway = new NoGateway()) { // Do stuff here }
O método Dispose seria chamado automaticamente quando a execução chegasse ao final do bloco using ou o cliente precisa chamar manualmente o método de descarte? ie
NoGateway objNoGateway = new NoGateway(); // Do stuff with object objNoGateway.Dispose(); // finished with it
Eu estou usando a
WebClient
classe na minhaNoGateway
classe. ComoWebClient
implementa aIDisposable
interface, isso significa queWebClient
indiretamente usa recursos não gerenciados? Existe uma regra rígida e rápida para seguir isso? Como sei que uma classe usa recursos não gerenciados?