开发者

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

开发者 https://www.devze.com 2023-03-07 06:33 出处:网络
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.

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开发者_StackOverflow 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)
{
    ...
}


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


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

using (WebClient webClient = new WebClient())
{
    // Your business in here...
}


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();
            }
        }


WebClient does not implement the iDisposable interface so there is nothing special that needs to be done to allow for proper garbage collection. When the CLR detects that there are no current references to the object, it will be scheduled for garbage collection. Of course you don't know just when that will occur so the memory may or may not (most likely not) be freed up immediately.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号