Udostępnij przez


Transfery w tle

Użyj interfejsu API transferu w tle, aby niezawodnie kopiować pliki przez sieć. Interfejs API transferu w tle udostępnia zaawansowane funkcje przekazywania i pobierania, które działają w tle podczas zawieszenia aplikacji i utrzymują się poza kończeniem działania aplikacji. Interfejs API monitoruje stan sieci i w przypadku utraty łączności automatycznie wstrzymuje i wznawia transfery. Transfery uwzględniają także zarządzanie danymi i baterią, co oznacza, że aktywność pobierania dostosowuje się w zależności od bieżącej łączności i stanu baterii urządzenia. Interfejs API jest idealny do przekazywania i pobierania dużych plików przy użyciu protokołu HTTP(S). Protokół FTP jest również obsługiwany, ale tylko w przypadku pobierania.

Transfer w tle działa oddzielnie od aplikacji wywołującej i jest przeznaczony przede wszystkim do obsługi długoterminowych operacji transferu dla zasobów, takich jak wideo, muzyka i duże obrazy. W przypadku tych scenariuszy korzystanie z transferu w tle jest niezbędne, ponieważ pobieranie będzie kontynuowane nawet wtedy, gdy aplikacja jest zawieszona.

Jeśli pobierasz małe zasoby, które prawdopodobnie zostaną szybko ukończone, użyj interfejsów API HttpClient zamiast Transferu w tle.

Korzystanie z funkcji Windows.Networking.BackgroundTransfer

Jak działa funkcja transferu w tle?

Gdy aplikacja używa transferu w tle do inicjowania transferu, żądanie jest konfigurowane i inicjowane przy użyciu obiektów klasy BackgroundDownloader lub BackgroundUploader. Każda operacja transferu jest obsługiwana indywidualnie przez system i oddzielona od aplikacji wywołującej. Informacje o postępie są dostępne, jeśli chcesz podać stan użytkownikowi w interfejsie użytkownika aplikacji, a aplikacja może wstrzymywać, anulować, wznawiać lub nawet odczytywać z danych podczas transferu. Sposób obsługi transferów przez system promuje inteligentne użycie energii i zapobiega problemom, które mogą wystąpić, gdy połączona aplikacja napotka zdarzenia, takie jak zawieszenie aplikacji, zakończenie lub nagłe zmiany stanu sieci.

Uwaga / Notatka

Ze względu na ograniczenia zasobów dla aplikacji aplikacja nie powinna mieć więcej niż 200 transferów (DownloadOperations + UploadOperations) w danym momencie. Przekroczenie tego limitu może spowodować, że kolejka transferu aplikacji znajdzie się w stanie nieodwracalnym.

Po uruchomieniu aplikacji należy wywołać AttachAsync na wszystkich istniejących obiektach DownloadOperation i UploadOperation. Nieuczynić tego spowoduje wyciek już ukończonych transferów i ostatecznie sprawi, że korzystanie z funkcji transferu w tle stanie się bezużyteczne.

Wykonywanie uwierzytelnionych żądań plików za pomocą transferu w tle

Transfer w tle udostępnia metody, które obsługują podstawowe poświadczenia serwera i serwera proxy, pliki cookie oraz użycie niestandardowych nagłówków HTTP (za pośrednictwem SetRequestHeader) dla każdej operacji transferu.

W jaki sposób ta funkcja dostosowuje się do zmian stanu sieci lub nieoczekiwanych zamykania?

Funkcja transferu w tle utrzymuje spójne środowisko dla każdej operacji transferu, gdy wystąpią zmiany stanu sieci, dzięki inteligentnemu wykorzystaniu informacji o stanie łączności i planu danych operatora udostępnianych przez funkcję Connectivity. Aby zdefiniować zachowanie dla różnych scenariuszy sieciowych, aplikacja ustawia zasady kosztów dla każdej operacji przy użyciu wartości zdefiniowanych przez BackgroundTransferCostPolicy.

Na przykład zasady kosztów zdefiniowane dla operacji mogą wskazywać, że operacja powinna zostać wstrzymana automatycznie, gdy urządzenie korzysta z sieci taryfowej. Transfer zostanie automatycznie wznowiony (lub ponownie uruchomiony), gdy zostanie nawiązane połączenie z siecią "nieograniczoną". Aby uzyskać więcej informacji na temat sposobu definiowania sieci według kosztów, zobacz NetworkCostType.

Chociaż funkcja transferu w tle ma własne mechanizmy obsługi zmian stanu sieci, istnieją inne ogólne zagadnienia dotyczące łączności dla aplikacji połączonych z siecią. Aby uzyskać dodatkowe informacje, przeczytaj Korzystanie z dostępnych informacji o połączeniu sieci.

Uwaga W przypadku aplikacji działających na urządzeniach przenośnych istnieją funkcje, które umożliwiają użytkownikowi monitorowanie i ograniczanie ilości przesyłanych danych na podstawie typu połączenia, stanu roamingu i planu danych użytkownika. W związku z tym transfery w tle mogą być wstrzymane na telefonie nawet wtedy, gdy BackgroundTransferCostPolicy wskazuje, że transfer powinien być kontynuowany.

W poniższej tabeli przedstawiono, kiedy transfery w tle są dozwolone na telefonie dla każdego BackgroundTransferCostPolicy wartości, biorąc pod uwagę bieżący stan telefonu. Aby określić bieżący stan telefonu, możesz użyć klasy ConnectionCost.

Stan urządzenia Bez ograniczeńOnly Wartość domyślna Zawsze
Połączono z siecią Wi-Fi Pozwól Pozwól Pozwól
Połączenie z opłatą za transfer danych, a nie roaming, nie przekraczając limitu danych, na dobrej drodze, aby nie przekroczyć limitu Odmów Pozwól Pozwól
Połączenie taryfowe, nie roaming, w ramach limitu danych, ale na dobrej drodze do przekroczenia limitu. Odmów Odmów Pozwól
Połączenie ograniczone, roaming, pod limitem danych Odmów Odmów Pozwól
Połączenie taryfowe przekracza limit danych. Ten stan występuje tylko wtedy, gdy użytkownik włączy opcję "Ogranicz dane w tle w interfejsie użytkownika czujnika danych. Odmów Odmów Odmów

Przekazywanie plików

W przypadku korzystania z transferu w tle przesyłanie występuje jako UploadOperation, który udostępnia szereg metod kontroli używanych do ponownego uruchomienia lub anulowania operacji. Zdarzenia aplikacji (na przykład zawieszenie lub zakończenie) i zmiany łączności są obsługiwane automatycznie przez system na UploadOperation; przesyłanie będzie kontynuowane w okresach zawieszenia aplikacji i trwało poza zakończeniem działania aplikacji. Ponadto ustawienie właściwości CostPolicy wskazuje, czy aplikacja rozpocznie przesyłanie danych, jeśli korzysta się z sieci taryfowej do połączenia z Internetem.

Poniższe przykłady przeprowadzą Cię przez proces tworzenia i inicjalizację podstawowej operacji przesyłania oraz jak wyliczyć i przywrócić operacje utrwalone z poprzedniej sesji aplikacji.

Przekazywanie pojedynczego pliku

Rozpoczęcie przesyłania rozpoczyna się od BackgroundUploader. Ta klasa służy do udostępniania metod umożliwiających aplikacji skonfigurowanie przesyłania przed utworzeniem wynikowej operacji przesyłania . W poniższym przykładzie pokazano, jak to zrobić za pomocą wymaganych Uri i obiektów StorageFile.

identyfikowanie pliku i miejsca docelowego przekazywania

Zanim zaczniemy od utworzenia UploadOperation, najpierw musimy zidentyfikować URI lokalizacji, do której będzie przekazywany plik, oraz sam plik, który zostanie przekazany. W poniższym przykładzie wartość uriString jest wypełniana przy użyciu ciągu znaków z danych wejściowych interfejsu użytkownika, a wartość pliku przy użyciu obiektu StorageFile zwróconego przez operację PickSingleFileAsync.

function uploadFile() {
    var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
    filePicker.fileTypeFilter.replaceAll(["*"]);

    filePicker.pickSingleFileAsync().then(function (file) {
        if (!file) {
            printLog("No file selected");
            return;
        }

        var upload = new UploadOp();
        var uriString = document.getElementById("serverAddressField").value;
        upload.start(uriString, file);

        // Store the upload operation in the uploadOps array.
        uploadOperations.push(upload);
    });
}

tworzenie i inicjowanie operacji przekazywania

W poprzednim kroku wartości uriString i plik są przekazywane do instancji naszego następnego przykładu, UploadOp, gdzie są one używane do skonfigurowania i uruchomienia nowej operacji przesyłania. Najpierw uriString jest analizowany w celu utworzenia wymaganego obiektu Uri.

Następnie właściwości podanego pliku StorageFile (plik) są używane przez BackgroundUploader, aby wypełnić nagłówek żądania i ustawić właściwość SourceFile za pomocą obiektu StorageFile. Następnie wywoływana jest metoda SetRequestHeader, aby wstawić nazwę pliku podaną jako ciąg i właściwość StorageFile.Name.

Na końcu BackgroundUploader tworzy UploadOperation (przesyłu).

function UploadOp() {
    var upload = null;
    var promise = null;

    this.start = function (uriString, file) {
        try {
        
            var uri = new Windows.Foundation.Uri(uriString);
            var uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();

            // Set a header, so the server can save the file (this is specific to the sample server).
            uploader.setRequestHeader("Filename", file.name);

            // Create a new upload operation.
            upload = uploader.createUpload(uri, file);

            // Start the upload and persist the promise to be able to cancel the upload.
            promise = upload.startAsync().then(complete, error, progress);
        } catch (err) {
            displayError(err);
        }
    };
    // On application activation, reassign callbacks for a upload
    // operation persisted from previous application state.
    this.load = function (loadedUpload) {
        try {
            upload = loadedUpload;
            promise = upload.attachAsync().then(complete, error, progress);
        } catch (err) {
            displayError(err);
        }
    };
}

Zwróć uwagę na wywołania metody asynchronicznej zdefiniowane przy użyciu obietnic języka JavaScript. Patrząc na wiersz z ostatniego przykładu:

promise = upload.startAsync().then(complete, error, progress);

Po then wywołaniu metody asynchronicznej następuje instrukcja wskazująca metody zdefiniowane przez aplikację, które są wywoływane, gdy zostanie zwrócony wynik wywołania metody asynchronicznej. Aby uzyskać więcej informacji na temat tego wzorca programowania, zobacz Programowanie asynchroniczne w języku JavaScript przy użyciu obietnic.

Przekazywanie wielu plików

zidentyfikuj pliki i miejsce docelowe przekazywania

W scenariuszu obejmującym wiele plików przesyłanych w ramach pojedynczej operacji przesyłania (UploadOperation), proces rozpoczyna się standardowo, od podania wymaganego identyfikatora URI miejsca docelowego oraz informacji o lokalnym pliku. Podobnie jak w przykładzie w poprzedniej sekcji, identyfikator URI jest dostarczany jako ciąg przez użytkownika końcowego i FileOpenPicker może służyć do zapewnienia możliwości wskazywania plików za pośrednictwem interfejsu użytkownika. Jednak w tym scenariuszu aplikacja powinna wywołać metodę PickMultipleFilesAsync, aby umożliwić wybór wielu plików za pośrednictwem interfejsu użytkownika.

function uploadFiles() {
       var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
       filePicker.fileTypeFilter.replaceAll(["*"]);

       filePicker.pickMultipleFilesAsync().then(function (files) {
          if (files === 0) {
             printLog("No file selected");
                return;
          }

          var upload = new UploadOperation();
          var uriString = document.getElementById("serverAddressField").value;
          upload.startMultipart(uriString, files);

          // Persist the upload operation in the global array.
          uploadOperations.push(upload);
       });
    }

Utwórz obiekty dla podanych parametrów

W dwóch następnych przykładach użyto kodu zawartego w jednej przykładowej metodzie, startMultipart, która została wywołana na końcu ostatniego kroku. Na potrzeby wyjaśnienia działania, kod w metodzie, która tworzy tablicę obiektów BackgroundTransferContentPart, został oddzielony od kodu, który tworzy wynikowy UploadOperation.

Najpierw ciąg URI dostarczony przez użytkownika jest inicjowany jako Uri. Następnie tablica obiektów IStorageFile (plików) przekazywanych do tej metody jest iterowana, każdy obiekt służy do utworzenia nowego obiektu BackgroundTransferContentPart, który następnie jest umieszczany w tablicy contentParts.

    upload.startMultipart = function (uriString, files) {
        try {
            var uri = new Windows.Foundation.Uri(uriString);
            var uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();

            var contentParts = [];
            files.forEach(function (file, index) {
                var part = new Windows.Networking.BackgroundTransfer.BackgroundTransferContentPart("File" + index, file.name);
                part.setFile(file);
                contentParts.push(part);
            });

Tworzenie i inicjowanie wieloczęściowej operacji przesyłania

Gdy nasza tablica contentParts jest zawierająca wszystkie obiekty BackgroundTransferContentPart, które reprezentują każdy IStorageFile do przekazania, możemy wywołać CreateUploadAsync przy użyciu identyfikatora Uri w celu wskazania miejsca, do którego zostanie wysłane żądanie.

        // Create a new upload operation.
            uploader.createUploadAsync(uri, contentParts).then(function (uploadOperation) {

               // Start the upload and persist the promise to be able to cancel the upload.
               upload = uploadOperation;
               promise = uploadOperation.startAsync().then(complete, error, progress);
            });

         } catch (err) {
             displayError(err);
         }
     };

Ponowne uruchamianie przerwanych operacji przekazywania

Po zakończeniu lub anulowaniu UploadOperation, zostaną zwolnione wszystkie skojarzone zasoby systemowe. Jeśli jednak aplikacja zostanie zakończona przed wystąpieniem któregokolwiek z tych elementów, wszystkie aktywne operacje zostaną wstrzymane, a zasoby skojarzone z każdym z nich pozostaną zajęte. Jeśli te operacje nie zostaną wyliczone i ponownie wprowadzone do następnej sesji aplikacji, nie zostaną one ukończone i będą nadal zajmować zasoby urządzeń.

  1. Przed zdefiniowaniem funkcji, która wylicza utrwalone operacje, należy utworzyć tablicę zawierającą obiekty UploadOperation, które zostaną zwrócone:

    var uploadOperations = [];
    
  2. Następnie zdefiniujemy funkcję, która wylicza utrwalone operacje i przechowuje je w naszej tablicy. Należy pamiętać, że metoda ładowania wywoływana w celu ponownego przypisania wywołań zwrotnych do UploadOperation, jeśli będzie ona utrzymywana po zakończeniu działania aplikacji, znajduje się w klasie UploadOp zdefiniowanej w dalszej części tej sekcji.

    function Windows.Networking.BackgroundTransfer.BackgroundUploader.getCurrentUploadsAsync() {
        .then(function (uploads) {
            for (var i = 0; i < uploads.size; i++) {
                var upload = new UploadOp();
                upload.load(uploads[i]);
                uploadOperations.push(upload);
            }
        }
    };
    

Pobieranie plików

W przypadku korzystania z transferu w tle każde pobieranie jest reprezentowane jako DownloadOperation, który zapewnia dostęp do wielu metod kontroli do pauzy, wznawiania, ponownego uruchamiania oraz anulowania operacji. Zdarzenia aplikacji (na przykład zawieszenie lub zakończenie) i zmiany łączności są obsługiwane automatycznie przez system w ramach DownloadOperation; pobieranie będzie kontynuowane podczas okresów zawieszenia aplikacji i będzie trwało także po jej zakończeniu. W przypadku scenariuszy sieci komórkowej ustawienie właściwości CostPolicy wskazuje, czy aplikacja rozpocznie lub nie rozpocznie pobierania, podczas gdy taryfowa sieć jest używana na potrzeby łączności z Internetem.

Jeśli pobierasz małe zasoby, które prawdopodobnie zostaną szybko ukończone, użyj interfejsów API HttpClient zamiast Transferu w tle.

Poniższe przykłady przeprowadzą Cię przez proces tworzenia i inicjowania podstawowego pobierania oraz sposobu wyliczania i ponownego inicjowania operacji utrwałych z poprzedniej sesji aplikacji.

Konfigurowanie i uruchamianie pobierania pliku transferu w tle

W poniższym przykładzie pokazano, jak ciągi reprezentujące URI i nazwę pliku mogą służyć do utworzenia obiektu Uri oraz StorageFile, który będzie zawierać żądany plik. W tym przykładzie nowy plik jest automatycznie umieszczany w wstępnie zdefiniowanej lokalizacji. Alternatywnie FileSavePicker można użyć, aby umożliwić użytkownikom wskazanie miejsca zapisania pliku na urządzeniu. Należy pamiętać, że metoda ładowania wywoływana w celu ponownego przypisania wywołań zwrotnych do DownloadOperation, jeśli będzie ona utrzymywana po zakończeniu działania aplikacji, znajduje się w klasie DownloadOp zdefiniowanej w dalszej części tej sekcji.

function DownloadOp() {
    var download = null;
    var promise = null;
    var imageStream = null;

    this.start = function (uriString, fileName) {
        try {
            // Asynchronously create the file in the pictures folder.
            Windows.Storage.KnownFolders.picturesLibrary.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.generateUniqueName).done(function (newFile) {
                var uri = Windows.Foundation.Uri(uriString);
                var downloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader();

                // Create a new download operation.
                download = downloader.createDownload(uri, newFile);

                // Start the download and persist the promise to be able to cancel the download.
                promise = download.startAsync().then(complete, error, progress);
            }, error);
        } catch (err) {
            displayException(err);
        }
    };
    // On application activation, reassign callbacks for a download
    // operation persisted from previous application state.
    this.load = function (loadedDownload) {
        try {
            download = loadedDownload;
            printLog("Found download: " + download.guid + " from previous application run.<br\>");
            promise = download.attachAsync().then(complete, error, progress);
        } catch (err) {
            displayException(err);
        }
    };
}

Zwróć uwagę na wywołania metody asynchronicznej zdefiniowane przy użyciu obietnic języka JavaScript. Patrząc na wiersz 17 z poprzedniego przykładu kodu:

promise = download.startAsync().then(complete, error, progress);

Po wywołaniu metody asynchronicznej następuje instrukcja then, która wskazuje metody zdefiniowane przez aplikację, które są wywoływane, gdy zostanie zwrócony wynik wywołania metody asynchronicznej. Aby uzyskać więcej informacji na temat tego wzorca programowania, zobacz Programowanie asynchroniczne w języku JavaScript przy użyciu obietnic.

Dodawanie dodatkowych metod sterowania operacjami

Poziom kontroli można zwiększyć, implementując dodatkowe metody DownloadOperation. Na przykład dodanie poniższego kodu do powyższego przykładu spowoduje wprowadzenie możliwości anulowania pobierania.

// Cancel download.
this.cancel = function () {
    try {
        if (promise) {
            promise.cancel();
            promise = null;
            printLog("Canceling download: " + download.guid + "<br\>");
            if (imageStream) {
                imageStream.close();
            }
        }
        else {
            printLog("Download " + download.guid + " already canceled.<br\>");
        }
    } catch (err) {
        displayException(err);
    }
};

Wyliczanie trwałych operacji podczas uruchamiania

Po zakończeniu lub anulowaniu DownloadOperationzostaną zwolnione wszystkie skojarzone zasoby systemowe. Jeśli jednak aplikacja zostanie zakończona przed wystąpieniem jednego z tych zdarzeń, pobieranie zostanie wstrzymane i utrwalone w tle. W poniższych przykładach pokazano, jak ponownie wprowadzić utrwalone pliki do nowej sesji aplikacji.

  1. Przed zdefiniowaniem funkcji, która wylicza utrwalone operacje, należy utworzyć tablicę zawierającą DownloadOperation obiekty, które zostaną zwrócone:

    var downloadOps = [];
    
  2. Następnie zdefiniujemy funkcję, która wylicza utrwalone operacje i przechowuje je w naszej tablicy. Należy pamiętać, że metoda ładowania wywoływana w celu ponownego przypisania wywołań zwrotnych dla utrwalonego DownloadOperation znajduje się w przykładzie DownloadOp zdefiniowanym w dalszej części tej sekcji.

    // Enumerate outstanding downloads.
    Windows.Networking.BackgroundTransfer.BackgroundDownloader.getCurrentDownloadsAsync().done(function (downloads) {
    
        for (var i = 0; i < downloads.size; i++) {
            var download = new DownloadOp();
            download.load(downloads[i]);
            downloadOps.push(download);
        }
    });
    
  3. Teraz możesz użyć wypełnionej listy, aby ponownie uruchomić oczekujące operacje.

Przetwarzanie końcowe

Nowa funkcja w systemie Windows 10 to możliwość uruchamiania kodu aplikacji po zakończeniu transferu w tle nawet wtedy, gdy aplikacja nie jest uruchomiona. Na przykład aplikacja może chcieć zaktualizować listę dostępnych filmów po zakończeniu pobierania filmu, zamiast skanować aplikację pod kątem nowych filmów przy każdym uruchomieniu. Możesz też chcieć obsłużyć nieudany transfer plików, próbując ponownie użyć innego serwera lub portu. Post-processing jest wywoływane zarówno dla pomyślnych, jak i dla nieudanych transferów, dzięki czemu można go użyć do zaimplementowania niestandardowej obsługi błędów i logiki powtarzania prób.

Przetwarzanie po przetworzeniu korzysta z istniejącej infrastruktury zadań w tle. Przed rozpoczęciem transferów należy utworzyć zadanie w tle i skojarzyć je z transferami. Transfery są następnie wykonywane w tle, a po ich zakończeniu zadanie w tle jest wywoływane w celu wykonania przetwarzania końcowego.

Przetwarzanie końcowe używa nowej klasy BackgroundTransferCompletionGroup. Ta klasa jest podobna do istniejącej BackgroundTransferGroup, w której umożliwia grupowanie transferów w tle, ale BackgroundTransferCompletionGroup dodaje możliwość wyznaczenia zadania w tle do uruchomienia po zakończeniu transferu.

Rozpocznij transfer w tle z przetwarzaniem końcowym w następujący sposób.

  1. Utwórz obiekt BackgroundTransferCompletionGroup. Następnie utwórz obiekt BackgroundTaskBuilder. Ustaw właściwość Trigger obiektu konstruktora na obiekt grupy ukończenia, a właściwość TaskEntryPoint konstruktora na punkt wejścia zadania w tle, które powinno zostać wykonane po zakończeniu transferu. Na koniec wywołaj metodę BackgroundTaskBuilder.Register, aby zarejestrować zadanie w tle. Należy pamiętać, że wiele grup zakończenia może współdzielić jeden punkt wejścia zadania w tle, ale można mieć tylko jedną grupę zakończenia przy jednej rejestracji zadania w tle.
var completionGroup = new BackgroundTransferCompletionGroup();
BackgroundTaskBuilder builder = new BackgroundTaskBuilder();

builder.Name = "MyDownloadProcessingTask";
builder.SetTrigger(completionGroup.Trigger);
builder.TaskEntryPoint = "Tasks.BackgroundDownloadProcessingTask";

BackgroundTaskRegistration downloadProcessingTask = builder.Register();
  1. Następnie skojarzysz transfery w tle z grupą finalizacji. Po utworzeniu wszystkich transferów włącz grupę uzupełniania.
BackgroundDownloader downloader = new BackgroundDownloader(completionGroup);
DownloadOperation download = downloader.CreateDownload(uri, file);
Task<DownloadOperation> startTask = download.StartAsync().AsTask();

// App still sees the normal completion path
startTask.ContinueWith(ForegroundCompletionHandler);

// Do not enable the CompletionGroup until after all downloads are created.
downloader.CompletionGroup.Enable();
  1. Kod w zadaniu w tle wyodrębnia listę operacji ze szczegółów wyzwalacza, a kod może następnie sprawdzić szczegóły każdej operacji i wykonać odpowiednie przetwarzanie końcowe dla każdej operacji.
public class BackgroundDownloadProcessingTask : IBackgroundTask
{
    public async void Run(IBackgroundTaskInstance taskInstance)
    {
    var details = (BackgroundTransferCompletionGroupTriggerDetails)taskInstance.TriggerDetails;
    IReadOnlyList<DownloadOperation> downloads = details.Downloads;

    // Do post-processing on each finished operation in the list of downloads
    }
}

Zadanie po przetwarzaniu jest zwykłym zadaniem w tle. Jest ona częścią puli wszystkich zadań w tle i podlega tym samym zasadom zarządzania zasobami co wszystkie zadania w tle.

Należy również pamiętać, że przetwarzanie końcowe nie zastępuje obsługi zakończenia działań w głównym wątku. Jeśli Twoja aplikacja definiuje funkcję obsługi ukończenia w pierwszym planie i aplikacja jest uruchomiona, gdy transfer plików się zakończy, wywołane zostaną zarówno funkcja obsługi ukończenia w pierwszym planie, jak i funkcja obsługi zakończenia w tle. Kolejność wywoływanych zadań pierwszego planu i zadań w tle nie jest gwarantowana. Jeśli zdefiniujesz oba te zadania, upewnij się, że te dwa zadania będą działać prawidłowo i nie zakłócają ich współbieżnego działania.

Limity czasu żądania

Istnieją dwa podstawowe scenariusze przekroczenia limitu czasu połączenia, które należy wziąć pod uwagę:

  • Podczas ustanawiania nowego połączenia dla transferu żądanie połączenia zostanie przerwane, jeśli nie zostanie ustanowione w ciągu pięciu minut.

  • Po nawiązaniu połączenia zostanie przerwany komunikat żądania HTTP, który nie odebrał odpowiedzi w ciągu dwóch minut.

Uwaga W obu scenariuszach, przy założeniu, że istnieje łączność z Internetem, transfer w tle ponowi żądanie do trzech razy automatycznie. W przypadku, gdy łączność z Internetem nie zostanie wykryta, dodatkowe żądania będą czekać, aż łączność zostanie przywrócona.

Wskazówki dotyczące debugowania

Zatrzymanie sesji debugowania w programie Microsoft Visual Studio jest porównywalne z zamknięciem aplikacji; Przekazywanie PUT jest wstrzymane, a przekazywanie POST zostało zakończone. Nawet podczas debugowania aplikacja powinna wyliczać, a następnie ponownie uruchomić lub anulować wszystkie zapisane przesyłania. Na przykład możesz anulować wyliczone utrwalone operacje przesyłania podczas uruchamiania aplikacji, jeśli poprzednie operacje nie są istotne dla tej sesji debugowania.

Podczas wyliczania pobrań/przesyłania przy uruchamianiu aplikacji w trakcie sesji debugowania, możesz anulować te procesy, jeśli nie są już potrzebne w tej sesji. Należy pamiętać, że jeśli istnieją aktualizacje projektu programu Visual Studio, takie jak zmiany w manifeście aplikacji, a aplikacja zostanie odinstalowana i wdrożona ponownie, GetCurrentUploadsAsync nie może wyliczyć operacji utworzonych przy użyciu poprzedniego wdrożenia aplikacji.

W przypadku używania Background Transfer podczas opracowywania może dojść do sytuacji, w której wewnętrzna pamięć podręczna dla aktywnych i ukończonych operacji transferu może wyjść z synchronizacji. Może to spowodować brak możliwości rozpoczęcia nowych operacji transferu lub interakcji z istniejącymi operacjami oraz obiektami BackgroundTransferGroup. W niektórych przypadkach próba interakcji z istniejącymi operacjami może spowodować awarię. Ten wynik może wystąpić, jeśli właściwość TransferBehavior jest ustawiona na Parallel. Ten problem występuje tylko w niektórych scenariuszach podczas programowania i nie ma zastosowania do użytkowników końcowych aplikacji.

Cztery scenariusze korzystające z programu Visual Studio mogą powodować ten problem.

  • Możesz utworzyć nowy projekt o tej samej nazwie aplikacji co istniejący projekt, lecz w innym języku programowania (na przykład C++ lub C#).
  • W istniejącym projekcie można zmienić architekturę docelową (na przykład z x86 na x64).
  • W istniejącym projekcie można zmienić kulturę (na przykład z neutralnej na en-US).
  • Możesz dodać lub usunąć funkcję w manifeście pakietu (na przykład dodanie Enterprise Authentication) w istniejącym projekcie.

Regularna obsługa aplikacji, w tym aktualizacje manifestu, które dodają lub usuwają możliwości, nie wyzwalają tego problemu przy wdrożeniach dla użytkowników końcowych aplikacji. Aby obejść ten problem, całkowicie odinstaluj wszystkie wersje aplikacji i ponownie wdróż je za pomocą nowego języka, architektury, kultury lub możliwości. Można to zrobić za pomocą ekranu startowego lub programu PowerShell oraz polecenia cmdlet Remove-AppxPackage.

Wyjątki w pliku Windows.Networking.BackgroundTransfer

Wyjątek jest zgłaszany, gdy do konstruktora obiektu Windows.Foundation.Uri jest przekazywany nieprawidłowy ciąg identyfikatora URI (Uniform Resource Identifier).

.NET: typ Windows.Foundation.Uri jest wyświetlany jako System.Uri w językach C# i VB.

W językach C# i Visual Basic ten błąd można uniknąć, używając klasy System.Uri na platformie .NET 4.5 i jednej z metod System.Uri.TryCreate w celu przetestowania ciągu otrzymanego od użytkownika aplikacji przed utworzeniem identyfikatora URI.

W języku C++ nie ma metody, aby spróbować przekonwertować ciąg na identyfikator URI. Jeśli aplikacja pobiera dane wejściowe od użytkownika dla Windows.Foundation.Uri, konstruktor powinien znajdować się w bloku try/catch. Jeśli zostanie zgłoszony wyjątek, aplikacja może powiadomić użytkownika i zażądać nowej nazwy hosta.

Przestrzeń nazw Windows.Networking.backgroundTransfer zawiera wygodne metody pomocnicze i korzysta z wyliczeń w przestrzeni nazw Windows.Networking.Sockets do obsługi błędów. Może to być przydatne w przypadku obsługi określonych wyjątków sieciowych w różnych aplikacjach.

Błąd napotkany w metodzie asynchronicznej w przestrzeni nazw Windows.Networking.backgroundTransfer jest zwracany jako wartość HRESULT. Metoda BackgroundTransferError.GetStatus służy do konwertowania błędu sieciowego z operacji transferu w tle na wartość wyliczenia WebErrorStatus. Większość wartości wyliczenia WebErrorStatus odpowiada błędowi zwróconym przez natywną operację klienta HTTP lub FTP. Aplikacja może filtrować według określonych WebErrorStatus wartości wyliczenia w celu zmodyfikowania sposobu działania aplikacji w zależności od przyczyny wyjątku.

W przypadku błędów walidacji parametrów aplikacja może również użyć HRESULT z wyjątku, aby dowiedzieć się więcej szczegółowych informacji na temat błędu, który spowodował wyjątek. Możliwe wartości HRESULT są wymienione w pliku nagłówkowym Winerror.h. W przypadku większości błędów walidacji parametrów HRESULT zwracany jest jako E_INVALIDARG.

Ważne interfejsy API