У службы фоновой передачи WP есть утечка памяти?

Недавно я обнаружил, что у службы фоновой передачи Windows Phone есть проблема с утечкой памяти.

Каждая добавленная вами фоновая передача займет место в памяти, которое не может быть удалено GC навсегда.

Я уже прочитал http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh202959(v=vs.105).aspx, и до сих пор не знаю, откуда происходит утечка памяти.

То, что я тестирую, очень просто: добавьте запрос фоновой передачи в Background Transfer Service, а когда этот запрос будет выполнен, удалите его из Background Transfer Service и добавьте еще один. Если я продолжу это делать, я увижу, что память растет, даже когда вызывается GC.collect каждую секунду. Пожалуйста, загрузите тестовый код в http://hdtp.synology.me/BTS.zip и вы поймете, что я говорю. Ниже приведена сводка кода тестирования.

    private int _transferCount = 1000;
private void CreateTask()
{
    if (--_transferCount < 0)
    {
        MessageBox.Show("End");
        return;
    }

    // Get the URI of the file to be transferred from the Tag property
    // of the button that was clicked.
    //string transferFileName = ((Button)sender).Tag as string;
    string transferFileName = "http://hdtp.synology.me/a.jpg";
    Uri transferUri = new Uri(Uri.EscapeUriString(transferFileName + "?ranNum=" + _transferCount), UriKind.RelativeOrAbsolute);

    // Create the new transfer request, passing in the URI of the file to 
    // be transferred.
    BackgroundTransferRequest transferRequest = new BackgroundTransferRequest(transferUri);

    // Set the transfer method. GET and POST are supported.
    transferRequest.Method = "GET";

    // Get the file name from the end of the transfer Uri and create a local Uri 
    // in the "transfers" directory in isolated storage.
    string downloadFile = transferFileName.Substring(transferFileName.LastIndexOf("/") + 1);
    Uri downloadUri = new Uri("shared/transfers/" + downloadFile, UriKind.RelativeOrAbsolute);
    transferRequest.DownloadLocation = downloadUri;

    // Pass custom data with the Tag property. This value cannot be more than 4000 characters.
    // In this example, the friendly name for the file is passed. 
    transferRequest.Tag = downloadFile;

    // Add the transfer request using the BackgroundTransferService. Do this in 
    // a try block in case an exception is thrown.
    try
    {
        BackgroundTransferService.Add(transferRequest);
    }
    catch (InvalidOperationException ex)
    {
        // TBD - update when exceptions are finalized
        MessageBox.Show("Unable to add background transfer request. " + ex.Message);
    }
    catch (Exception)
    {
        MessageBox.Show("Unable to add background transfer request.");
    }

    InitialTansferStatusCheck();
}

private void InitialTansferStatusCheck()
{
    UpdateRequestsList();

    foreach (var transfer in transferRequests)
    {
        transfer.TransferStatusChanged += new EventHandler<BackgroundTransferEventArgs>(transfer_TransferStatusChanged);
        ProcessTransfer(transfer);
    }
}

private void transfer_TransferStatusChanged(object sender, BackgroundTransferEventArgs e)
{
    ProcessTransfer(e.Request);
}

private void UpdateRequestsList()
{
    // The Requests property returns new references, so make sure that
    // you dispose of the old references to avoid memory leaks.
    if (transferRequests != null)
    {
        foreach (var request in transferRequests)
        {
            request.Dispose();
        }
    }
    transferRequests = BackgroundTransferService.Requests;
}

private void ProcessTransfer(BackgroundTransferRequest transfer)
{
    switch (transfer.TransferStatus)
    {
        case TransferStatus.Completed:

            // If the status code of a completed transfer is 200 or 206, the
            // transfer was successful
            if (transfer.StatusCode == 200 || transfer.StatusCode == 206)
            {
                // Remove the transfer request in order to make room in the 
                // queue for more transfers. Transfers are not automatically
                // removed by the system.
                RemoveTransferRequest(transfer.RequestId);

                // In this example, the downloaded file is moved into the root
                // Isolated Storage directory
                using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    string filename = transfer.Tag;
                    if (isoStore.FileExists(filename))
                    {
                        isoStore.DeleteFile(filename);
                    }
                    isoStore.MoveFile(transfer.DownloadLocation.OriginalString, filename);
                }

                CreateTask();
            }
            else
            {
                // This is where you can handle whatever error is indicated by the
                // StatusCode and then remove the transfer from the queue. 
                RemoveTransferRequest(transfer.RequestId);

                if (transfer.TransferError != null)
                {
                    // Handle TransferError, if there is one.
                }
            }
            break;
    }
}

private void RemoveTransferRequest(string transferID)
{
    // Use Find to retrieve the transfer request with the specified ID.
    BackgroundTransferRequest transferToRemove = BackgroundTransferService.Find(transferID);

    // try to remove the transfer from the background transfer service.
    try
    {
        BackgroundTransferService.Remove(transferToRemove);
    }
    catch (Exception ex)
    {

    }
}

Еще несколько вопросов, согласно приведенной выше документации, мы будем каждый раз получать новый экземпляр из BackgroundTransferService.Requests, но если я вызываю GetHashCode(), я получаю каждый раз один и тот же хэш-код, и хэш-код даже совпадает с один я обновил и добавил в Background Transfer Service. Так это потому, что MS переопределяет метод GetHashCode в BackgroundTransferRequest? или я что-то неправильно понимаю. Но в приведенном выше примере кода я не использовал BackgroundTransferService.Requests для получения какого-либо экземпляра, память все еще продолжает расти.

Пожалуйста, скажите мне, что я делаю не так или любой обходной путь, спасибо...

0 ответов

Другие вопросы по тегам