问题
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)
{
...
}
回答1:
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.
回答2:
The SilverLight version of WebClient doesn't implement IDisposable
. You are doing it right - webClient
will be automatically garbage collected when the time comes.
回答3:
Instead of manually disposing of WebClient you could just put it in a using block.
using (WebClient webClient = new WebClient())
{
// Your business in here...
}
回答4:
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();
}
}
来源:https://stackoverflow.com/questions/6063079/will-an-object-be-disposed-automatically-after-an-asynchronous-event-it-subscrib