Будет ли объект удален автоматически после возникновения асинхронного события, на которое он подписан? - PullRequest
7 голосов
/ 19 мая 2011

Предположим, у меня есть эта функция, которую можно вызывать несколько раз из основного потока.Каждый раз, когда это вызывается, я создаю WebClient объект для асинхронной загрузки некоторых данных.

Мой вопрос ... это безопасно делать?Выпускается ли объект WebClient после вызова события?Я не хотел бы продолжать выделять память, если она не будет освобождена автоматически.

Мое приложение для WP7 с Silverlight.

Спасибо!

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)
{
    ...
}

Ответы [ 4 ]

4 голосов
/ 24 сентября 2014

Вместо того, чтобы вручную утилизировать WebClient, вы можете просто поместить его в блок использования.

using (WebClient webClient = new WebClient())
{
    // Your business in here...
}
4 голосов
/ 19 мая 2011

SilverLight версия WebClient не поддерживает IDisposable.Вы все делаете правильно - webClient будет автоматически собирать мусор, когда придет время.

1 голос
/ 19 мая 2011

Я вижу 2 проблемы. Во-первых, веб-клиент не размещается во всех возможных ситуациях, во-вторых, ссылка на Веб-клиент будет сохранена, поскольку вы никогда не отмените подписку на событие.

Я думаю, что это близко к этому (хотя все еще не идеально, подумайте о 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();
            }
        }
0 голосов
/ 19 мая 2011

WebClient не реализует интерфейс iDisposable, поэтому нет ничего особенного, что необходимо сделать для правильной сборки мусора.Когда CLR обнаруживает отсутствие текущих ссылок на объект, он будет запланирован для сборки мусора.Конечно, вы не знаете, когда это произойдет, поэтому память может или не может (скорее всего, нет) быть немедленно освобождена.

...