Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will an object be disposed automatically after an asynchronous event it subscribed to is raised?

Let's suppose I have this function that can be called several times from the main thread. Every time this is called, I create a WebClient object to download some data asynchronously.

My question... is this safe to do? Is the WebClient object released after the event is called? I wouldn't like to keep allocating memory if it is not going to be freed automatically.

My application is for WP7 with Silverlight.

Thanks!

void DownloadData(string cURL)
{
    WebClient webClient = new WebClient();
    webClient.DownloadStringCompleted +=
       new System.Net.DownloadStringCompletedEventHandler(
            webClient_DownloadStringCompleted);
    webClient.DownloadStringAsync(new Uri(cURL));
}

static void webClient_DownloadStringCompleted(object sender,
                      System.Net.DownloadStringCompletedEventArgs e)
{
    ...
}
like image 859
LEM Avatar asked May 19 '11 18:05

LEM


3 Answers

The SilverLight version of WebClient doesn't implement IDisposable. You are doing it right - webClient will be automatically garbage collected when the time comes.

like image 98
Greg Avatar answered Oct 20 '22 16:10

Greg


Instead of manually disposing of WebClient you could just put it in a using block.

using (WebClient webClient = new WebClient())
{
    // Your business in here...
}
like image 4
kbo4sho88 Avatar answered Oct 20 '22 16:10

kbo4sho88


I see 2 problems. First of all, webclient isnt disposed in all possible situations, secondly a reference to WebClient will be maintained since you never unsubscribe the event.

I think this comes close to it (still not perfect though, think about ThreadAborted):

void DownloadData(string cURL) 
        {
            WebClient webClient = new WebClient();

            try
            {
                webClient.DownloadStringCompleted += new System.Net.DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
                webClient.DownloadStringAsync(new Uri(cURL));
            }
            catch
            {
                webClient.Dispose();
                throw;
            }
        }

        static void webClient_DownloadStringCompleted(object sender, System.Net.DownloadStringCompletedEventArgs e)
        {
            WebClient webClient = (WebClient)sender;

            webClient.DownloadStringCompleted -= webClient_DownloadStringCompleted;

            try
            {

            }
            finally
            {
                webClient.Dispose();
            }
        }
like image 1
Polity Avatar answered Oct 20 '22 14:10

Polity