Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
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 automatycznie wstrzymuje oraz wznawia transfery w przypadku utraty łączności. Transfery są również świadome funkcji Data Sense i Battery Sense, co oznacza, że aktywność pobierania jest dostosowywana na podstawie 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.
Note
Interfejsy API Windows.Networking.BackgroundTransfer to interfejsy API środowiska środowisko wykonawcze systemu Windows (WinRT), które działają zarówno w aplikacjach klasycznych korzystających z WinUI 3 (Zestaw SDK do aplikacji systemu Windows), jak i w aplikacjach UWP. Transfery w tle wymagają tożsamości pakietu; aplikacje rozpakowane nie mogą używać tego interfejsu API.
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órych pobieranie prawdopodobnie szybko się zakończy, użyj interfejsów API HttpClient zamiast Transferu w tle.
Korzystanie z 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 klas 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 pokazywać użytkownikowi stan w interfejsie użytkownika Twojej aplikacji, a sama aplikacja może wstrzymywać, wznawiać, anulować, a nawet odczytywać dane w trakcie 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.
Note
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 sprawić, że kolejka przesyłania aplikacji znajdzie się w stanie, którego nie da się przywrócić.
Po uruchomieniu aplikacji należy wywołać funkcję AttachAsync we wszystkich istniejących obiektach DownloadOperation i UploadOperation . Niewykonanie tej czynności spowoduje wycieki zasobów związanych z już ukończonymi transferami i ostatecznie sprawi, że korzystanie z funkcji transferu w tle stanie się bezużyteczne.
Wykonywanie uwierzytelnionych żądań plików za pomocą transferu w tle
Background Transfer udostępnia metody obsługujące podstawowe poświadczenia serwera oraz serwera proxy, pliki cookie i użycie niestandardowych nagłówków HTTP (za pośrednictwem SetRequestHeader) dla każdej operacji przesyłania.
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, inteligentnie wykorzystując informacje o stanie łączności i planu danych operatora udostępniane przez funkcję łączności . 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ą. Użyj interfejsów API Windows.Networking.Connectivity do monitorowania stanu połączenia i informacji o kosztach połączenia.
Note
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.
Poniższa tabela wskazuje, kiedy transfery w tle są dozwolone na telefonie dla każdej wartości BackgroundTransferCostPolicy , biorąc pod uwagę bieżący stan telefonu. Możesz użyć klasy ConnectionCost , aby określić bieżący stan telefonu.
| Stan urządzenia | Bez ograniczeńOnly | Default | Zawsze |
|---|---|---|---|
| Połączono z siecią Wi-Fi | Zezwól | Zezwól | Zezwól |
| Połączenie taryfowe, bez roamingu, poniżej limitu danych, na dobrej drodze, aby pozostać poniżej limitu | Deny | Zezwól | Zezwól |
| Połączenie taryfowe, bez roamingu, poniżej limitu danych, na dobrej drodze do przekroczenia limitu | Deny | Deny | Zezwól |
| Połączenie taryfowe, roaming, poniżej limitu danych | Deny | Deny | Zezwó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. | Deny | Deny | Deny |
Przekazywanie plików
W przypadku korzystania z transferu w tle operacja przekazywania jest reprezentowana przez UploadOperation, który udostępnia szereg metod sterujących używanych do ponownego uruchamiania lub anulowania operacji. Zdarzenia aplikacji (na przykład zawieszenie lub zakończenie) i zmiany łączności są obsługiwane automatycznie przez system dla każdego elementu UploadOperation; przesyłanie będzie kontynuowane w okresach zawieszenia aplikacji lub zostanie wstrzymane i zachowane po zakończeniu działania aplikacji. Ponadto ustawienie właściwości CostPolicy określa, czy aplikacja rozpocznie wysyłanie podczas korzystania z połączenia taryfowego z Internetem.
Poniższe przykłady przeprowadzą Cię przez proces tworzenia i inicjowania podstawowego przesyłania oraz przez sposób wyliczania i ponownego wprowadzania operacji zachowanych z poprzedniej sesji aplikacji.
Przekazywanie pojedynczego pliku
Tworzenie operacji przesyłania rozpoczyna się od elementu BackgroundUploader. Ta klasa służy do udostępniania metod, które umożliwiają aplikacji skonfigurowanie przesyłania przed utworzeniem wynikowego obiektu UploadOperation. W poniższym przykładzie pokazano, jak to zrobić z wymaganymi obiektami URI i StorageFile .
Identyfikowanie pliku i miejsca docelowego przekazywania
Zanim będziemy mogli przystąpić do utworzenia obiektu UploadOperation, najpierw musimy określić identyfikator URI lokalizacji docelowej przesyłania oraz plik, który zostanie przesłany. W poniższym przykładzie wartość uriString jest wypełniana przy użyciu ciągu 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 file są przekazywane do wystąpienia naszego następnego przykładu UploadOp, gdzie są używane do konfigurowania i uruchamiania nowej operacji przekazywania. Najpierw ciąg uriString jest analizowany składniowo, aby utworzyć wymagany obiekt Uri.
Następnie właściwości podanego pliku StorageFile (plik) są używane przez funkcję BackgroundUploader do wypełnienia nagłówka żądania i ustawiania właściwości 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 koniec funkcja BackgroundUploader tworzy operację UploadOperation (przekazywanie).
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. Spójrzmy na linię 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 Asynchroniczne programowanie w języku JavaScript przy użyciu obietnic.
Przekazywanie wielu plików
Identyfikowanie plików i miejsca docelowego przekazywania
W scenariuszu obejmującym wiele plików przesyłanych za pomocą pojedynczej operacji UploadOperation proces rozpoczyna się tak, jak zwykle, podając najpierw wymagany identyfikator URI miejsca docelowego i informacje o pliku lokalnym. Podobnie jak w przykładzie w poprzedniej sekcji, identyfikator URI jest dostarczany jako ciąg przez użytkownika końcowego i plikOtwórzPicker 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);
});
}
Tworzenie obiektów 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. Dla celów instruktażowych kod w metodzie tworzącej tablicę obiektów BackgroundTransferContentPart został oddzielony od kodu tworzącego wynikowy obiekt UploadOperation.
Najpierw ciąg URI podany przez użytkownika jest inicjalizowany jako Uri. Następnie wykonywana jest iteracja po tablicy obiektów IStorageFile (files) przekazanej do tej metody; każdy obiekt jest używany 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 operacji wieloczęściowego przesyłania
Mając tablicę contentParts wypełnioną wszystkimi obiektami BackgroundTransferContentPart reprezentującymi każdy obiekt IStorageFile do wysłania, możemy teraz wywołać metodę CreateUploadAsync, używając identyfikatora URI, aby wskazać, dokąd 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 operacji UploadOperation wszystkie skojarzone zasoby systemowe są zwalniane. 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ń.
Przed zdefiniowaniem funkcji, która wylicza utrwalone operacje, musimy utworzyć tablicę zawierającą obiekty UploadOperation , które będą zwracane:
var uploadOperations = [];Następnie zdefiniujemy funkcję, która wylicza utrwalone operacje i przechowuje je w naszej tablicy. Należy pamiętać, że metoda load, wywoływana w celu ponownego przypisania funkcji wywołania zwrotnego do obiektu UploadOperation, jeśli ma ona przetrwać zamknięcie aplikacji, znajduje się w klasie UploadOp, którą zdefiniujemy 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żdy plik pobierania istnieje jako element DownloadOperation , który uwidacznia wiele metod kontroli używanych do wstrzymania, wznawiania, ponownego uruchamiania i anulowania operacji. Zdarzenia aplikacji (na przykład zawieszenie lub zakończenie działania) oraz zmiany łączności są obsługiwane automatycznie przez system dla każdej operacji DownloadOperation; pobierania będą kontynuowane w okresach zawieszenia aplikacji albo zostaną wstrzymane i zachowane po zakończeniu działania aplikacji. W przypadku scenariuszy sieci mobilnych ustawienie właściwości CostPolicy będzie wskazywać, czy aplikacja rozpocznie lub będzie kontynuować pobieranie, podczas gdy taryfowa sieć jest używana na potrzeby łączności z Internetem.
Jeśli pobierasz małe zasoby, których pobieranie prawdopodobnie szybko się zakończy, 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 za pomocą funkcji Background Transfer
W poniższym przykładzie pokazano, jak ciągi reprezentujące identyfikator URI i nazwę pliku mogą służyć do utworzenia obiektu URI i pliku StorageFile , który będzie zawierać żądany plik. W tym przykładzie nowy plik jest automatycznie umieszczany w wstępnie zdefiniowanej lokalizacji. Alternatywnie można użyć narzędzia FileSavePicker , 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 metody DownloadOperation, jeśli będzie ona trwała 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 Asynchroniczne programowanie 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 operacji DownloadOperation wszystkie skojarzone zasoby systemowe są zwalniane. 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.
Przed zdefiniowaniem funkcji, która wylicza utrwalone operacje, należy utworzyć tablicę zawierającą obiekty DownloadOperation , które będą zwracane:
var downloadOps = [];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 elementu 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); } });Teraz możesz użyć wypełnionej listy, aby ponownie uruchomić oczekujące operacje.
Przetwarzanie końcowe
Nowa funkcja w 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. Przetwarzanie końcowe jest wywoływane zarówno po udanych, jak i nieudanych transferach, dzięki czemu można je wykorzystać do implementacji niestandardowej obsługi błędów i logiki ponawiania prób.
Przetwarzanie końcowe 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 grupy BackgroundTransferGroup , w której umożliwia grupowanie transferów w tle, ale funkcja BackgroundTransferCompletionGroup dodaje możliwość wyznaczenia zadania w tle do uruchomienia po zakończeniu transferu.
Transfer w tle z przetwarzaniem końcowym inicjuje się w następujący sposób.
- 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ć uruchomione po ukończeniu transferu. Na koniec wywołaj metodę BackgroundTaskBuilder.Register , aby zarejestrować zadanie w tle. Należy pamiętać, że wiele grup ukończenia może współdzielić jeden punkt wejścia dla zadania w tle, ale do jednej rejestracji zadania w tle może być przypisana tylko jedna grupa ukończenia.
var completionGroup = new BackgroundTransferCompletionGroup();
BackgroundTaskBuilder builder = new BackgroundTaskBuilder();
builder.Name = "MyDownloadProcessingTask";
builder.SetTrigger(completionGroup.Trigger);
builder.TaskEntryPoint = "Tasks.BackgroundDownloadProcessingTask";
BackgroundTaskRegistration downloadProcessingTask = builder.Register();
- Następnie skojarzysz transfery w tle z grupą uzupełniania. 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();
- 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 procedur obsługi zakończenia na pierwszym planie. Jeśli aplikacja definiuje procedurę obsługi zakończenia na pierwszym planie, a transfer pliku zakończy się, gdy aplikacja działa, zostaną wywołane zarówno procedura obsługi zakończenia na pierwszym planie, jak i procedura obsługi zakończenia w tle. Nie ma gwarancji co do kolejności wywoływania zadań pierwszego planu i zadań w tle. 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. Jeśli nie zostanie wykryte połączenie z Internetem, kolejne żądania będą czekać, aż zostanie ono wykryte.
Wskazówki dotyczące debugowania
Zatrzymanie sesji debugowania w Microsoft Visual Studio jest porównywalne z zamknięciem aplikacji; Przekazywanie PUT jest wstrzymane, a przekazywanie POST zostało zakończone. Nawet podczas debugowania Twoja aplikacja powinna wykryć, a następnie ponownie uruchomić lub anulować wszystkie trwale zapisane przesyłania. Na przykład podczas uruchamiania aplikacji możesz anulować wyliczone, zapisane operacje przesyłania, jeśli poprzednie operacje nie są istotne w tej sesji debugowania.
Podczas wyliczania operacji pobierania i wysyłania przy uruchamianiu aplikacji w trakcie sesji debugowania możesz sprawić, aby aplikacja anulowała je, jeśli poprzednie operacje z tej sesji debugowania nie są już potrzebne. Należy pamiętać, że jeśli w projekcie programu Visual Studio zostaną wprowadzone aktualizacje, takie jak zmiany w manifeście aplikacji, a następnie aplikacja zostanie odinstalowana i wdrożona ponownie, metoda GetCurrentUploadsAsync nie może wyliczać operacji utworzonych przy użyciu poprzednio wdrożonej wersji aplikacji.
W przypadku korzystania z transferu w tle podczas programowania może dojść do sytuacji, w której wewnętrzne pamięci podręczne aktywnych i ukończonych operacji transferu mogą wyjść z synchronizacji. Może to spowodować brak możliwości rozpoczęcia nowych operacji transferu lub interakcji z istniejącymi operacjami i 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 Visual Studio mogą powodować ten problem.
- Tworzysz nowy projekt o tej samej nazwie aplikacji jak istniejący projekt, ale w innym języku (na przykład z C++ na 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ąć możliwość w manifeście pakietu (na przykład dodanie uwierzytelniania przedsiębiorstwa) w istniejącym projekcie.
Regularne serwisowanie aplikacji, w tym aktualizacje manifestu, które dodają lub usuwają funkcje, nie powoduje tego problemu we wdrożeniach Twojej aplikacji u użytkowników końcowych. 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 za pomocą programu PowerShell i polecenia cmdlet Remove-AppxPackage .
Wyjątki w Windows.Networking.BackgroundTransfer
Wyjątek jest zgłaszany, gdy do konstruktora obiektu Windows.Foundation.Uri zostanie przekazany nieprawidłowy ciąg znaków dla identyfikatora URI (Uniform Resource Identifier).
.NET: Typ Windows.Foundation.Uri jest przedstawiany 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 w .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 umożliwiającej próbę przekształcenia ciągu znaków 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óconego przez natywną operację klienta HTTP lub FTP. Aplikacja może filtrować określone wartości wyliczenia WebErrorStatus , aby zmodyfikować zachowanie 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łówka Winerror.h . W przypadku większości błędów sprawdzania poprawności parametrów zwracany jest kod HRESULTE_INVALIDARG.