Transferts en arrière-plan

Utilisez l’API de transfert en arrière-plan pour copier des fichiers de manière fiable sur le réseau. L’API de transfert en arrière-plan offre des fonctionnalités avancées de chargement et téléchargement, qui s’exécutent en arrière-plan pendant la suspension d’une application, et perdurent après l’arrêt de l’application. L’API surveille l’état du réseau. Elle suspend et reprend automatiquement les transferts en cas de perte de connexion. Les transferts sont par ailleurs régis par l’Assistant Données et l’Assistant batterie, ce qui signifie que l’activité de téléchargement s’ajuste en fonction de l’état actuel de la batterie de l’appareil et de la connexion. L’API est idéale pour le chargement et le téléchargement de fichiers volumineux à l’aide du protocole HTTP(S). Le protocole FTP est également pris en charge, mais uniquement pour les téléchargements.

Le transfert en arrière-plan s’exécute séparément de l’application appelante et est principalement conçu pour des opérations de transfert à long terme pour des ressources telles que des vidéos, de la musique et des images volumineuses. Dans ces cas, l’utilisation du transfert en arrière-plan est essentielle, car les téléchargements se poursuivent même quand l’application est suspendue.

Si vous téléchargez peu de ressources et si l’opération est censée se terminer rapidement, utilisez les API HttpClient à la place du transfert en arrière-plan.

Utilisation de Windows.Networking.BackgroundTransfer

Comment la fonctionnalité de transfert en arrière-plan fonctionne-t-elle ?

Quand une application utilise la fonctionnalité de transfert en arrière-plan pour lancer un transfert, la requête est configurée et initialisée à l’aide d’objets de classe BackgroundDownloader ou BackgroundUploader. Chaque opération de transfert est gérée individuellement par le système et séparément de l’application appelante. Les informations sur la progression sont disponibles si vous voulez indiquer un état à l’utilisateur dans l’interface utilisateur de votre application. En outre, l’exécution de votre application peut être suspendue, reprise, annulée ou même lue à partir des données pendant le transfert. La manière dont les transferts sont gérés par le système favorise une consommation d’énergie intelligente et évite les problèmes qui peuvent se produire lorsqu’une application connectée se heurte à des événements tels qu’une interruption ou un arrêt de l’application, ou encore des modifications soudaines de l’état du réseau.

Notes

En raison des contraintes de ressource par application, une application ne doit pas effectuer plus de 200 transferts (DownloadOperations + UploadOperations) à un moment donné. Si cette limite est dépassée, cela peut mettre la file d’attente de transfert de l’application dans un état irrécupérable.

Lorsqu’une application est lancée, elle doit appeler AttachAsync sur tous les objets DownloadOperation et UploadOperation existants. Tout manquement entraîne la fuite des transferts déjà effectués et rend inutile votre utilisation de la fonctionnalité de transfert en arrière-plan.

Exécution de demandes de fichiers authentifiées avec le transfert en arrière-plan

Le transfert en arrière-plan fournit des méthodes qui prennent en charge les informations d’authentification serveur et proxy de base, les cookies et l’utilisation d’en-têtes HTTP personnalisés (par l’intermédiaire de la méthode SetRequestHeader) pour chaque opération de transfert.

Comment cette fonctionnalité s’adapte-t-elle aux modifications de l’état du réseau ou aux arrêts inattendus ?

La fonctionnalité de transfert en arrière-plan garantit une démarche cohérente pour chaque opération de transfert en cas de modification de l’état du réseau. Pour cela, elle exploite intelligemment les informations sur l’état de la connectivité et du forfait données de l’opérateur fournies par la fonctionnalité Connectivité. Afin de définir un comportement pour des scénarios réseau différents, une application définit une stratégie de coût pour chaque opération de transfert à l’aide de valeurs définies par BackgroundTransferCostPolicy.

Par exemple, la stratégie de coût définie pour une opération peut indiquer que l’opération doit être automatiquement suspendue lorsque l’appareil exploite une connexion réseau limitée. Le transfert reprend (ou redémarre) automatiquement ensuite dès qu’une connexion à un réseau « non restreint » est établie. Pour plus d’informations sur le mode de définition par coût des réseaux, voir NetworkCostType.

Bien que la fonctionnalité de transfert en arrière-plan possède ses propres mécanismes pour gérer les modifications de l’état du réseau, d’autres considérations générales ayant trait à la connectivité des applications connectées au réseau sont à prendre en compte. Pour plus d’informations, voir Exploitation des informations de connexion réseau disponibles.

Remarque Les applications pour appareils mobiles disposent de fonctionnalités qui permettent à l’utilisateur de surveiller et de limiter la quantité de données transférées en fonction du type de connexion, de l’état de l’itinérance et du forfait de données. C’est pourquoi les transferts en arrière-plan peuvent être suspendus sur le téléphone même quand BackgroundTransferCostPolicy indique que le transfert doit s’effectuer.

Le tableau suivant indique les moments où les transferts en arrière-plan sont autorisés sur le téléphone pour chaque valeur BackgroundTransferCostPolicy, en fonction de l’état actuel du téléphone. Vous pouvez utiliser la classe ConnectionCost pour déterminer l’état actuel du téléphone.

État de l’appareil UnrestrictedOnly Default Toujours
Connecté au Wi-Fi Autoriser Autoriser Autoriser
Connexion limitée, pas d’itinérance, sous la limite de données, en bonne voie pour rester sous la limite Deny Autoriser Autoriser
Connexion limitée, pas d’itinérance, sous la limite de données, en bonne voie pour dépasser la limite Deny Deny Autoriser
Connexion limitée, itinérance, sous la limite de données Deny Deny Autoriser
Connexion limitée, au-dessus de la limite de données. Cet état se produit uniquement quand l’utilisateur active la restriction des données en arrière-plan dans l’interface utilisateur Data Sense. Deny Deny Deny

Chargement de fichiers

Lorsque vous faites appel à la fonctionnalité de transfert en arrière-plan, le chargement qui en résulte existe sous la forme d’une opération UploadOperation qui expose de nombreuses méthodes de contrôle servant à redémarrer ou à annuler l’opération. Les événements d’application (par exemple, une suspension ou un arrêt) et les changements de connectivité sont gérés automatiquement par le système pour chaque opération UploadOperation. Les chargements se poursuivent lors des périodes de suspension des applications et perdurent après l’arrêt des applications. De plus, la propriété CostPolicy peut être définie pour indiquer si oui ou non votre application entamera des chargements tandis qu’une connexion réseau limitée est utilisée pour la connectivité Internet.

Les exemples qui suivent vous guident tout au long du processus de création et d’initialisation d’un chargement de base et décrivent comment énumérer des opérations de chargement issues d’une session d’application précédente.

Chargement d’un fichier unique

La création d’un chargement commence avec BackgroundUploader. Cette classe sert à fournir les méthodes qui permettent à votre application de configurer le chargement avant de créer l’objet UploadOperation qui en résulte. L’exemple qui suit montre comment y parvenir avec les objets Uri et StorageFile requis.

Identifier le fichier et la destination du chargement

Avant de commencer avec la création d’un objet UploadOperation, nous devons avant tout identifier l’URI du lieu de chargement, ainsi que le fichier qui sera chargé. Dans l’exemple qui suit, la valeur uriString est remplie au moyen d’une chaîne issue d’entrées de l’interface utilisateur et la valeur file est remplie à l’aide de l’objet StorageFile renvoyé par une opération 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);
    });
}

Créer et initialiser l’opération de chargement

Dans l’étape qui précède, les valeurs uriString et file sont transmises à une instance de notre exemple suivant, UploadOp, où elles sont utilisées pour configurer et lancer la nouvelle opération de chargement. Pour commencer, la valeur uriString est analysée afin de créer l’objet Uri requis.

Ensuite, les propriétés de l’objet StorageFile fourni (file) sont utilisées par la classe BackgroundUploader pour remplir l’en-tête de la demande et définir la propriété SourceFile à l’aide de l’objet StorageFile. La méthode SetRequestHeader est ensuite appelée pour insérer le nom de fichier, fourni comme chaîne, et la propriété StorageFile.Name.

Pour finir, BackgroundUploader crée l’objet UploadOperation (upload).

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);
        }
    };
}

Notez les appels de méthode asynchrone définis à l’aide de promesses JavaScript. Examinons une ligne du dernier exemple :

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

L'appel de méthode asynchrone est suivi d'une instruction then qui indique les méthodes, définies par l'application, qui sont appelées lorsqu'un résultat de l'appel de méthode asynchrone est renvoyé. Pour plus d’informations sur ce modèle de programmation, voir Programmation asynchrone en JavaScript à l’aide de promesses.

Chargement de plusieurs fichiers

Identifier les fichiers et la destination du chargement

Dans un scénario impliquant plusieurs fichiers transférés avec une seule opération UploadOperation, le processus commence comme habituellement en fournissant tout d’abord l’URI de destination et les informations de fichier local requis. Comme dans l’exemple de la section précédente, l’URI est fourni sous forme de chaîne par l’utilisateur final et FileOpenPicker peut être utilisé pour offrir la possibilité d’indiquer les fichiers par le biais de l’interface utilisateur également. Toutefois, dans ce scénario, l’application doit plutôt appeler la méthode PickMultipleFilesAsync pour permettre la sélection de plusieurs fichiers par le biais de l’interface utilisateur.

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);
       });
    }

Créer des objets pour les paramètres fournis

Les deux prochains exemples utilisent du code contenu dans un exemple de méthode unique, startMultipart, qui a été appelée à la fin de la dernière étape. Pour les besoins de l’instruction, le code présent dans la méthode qui crée un tableau d’objets BackgroundTransferContentPart a été séparé du code qui crée l’opération UploadOperation résultante.

D’abord, la chaîne d’URI fournie par l’utilisateur est initialisée en tant qu’Uri. Ensuite, une itération est effectuée sur le tableau d’objets IStorageFile (files) passés à cette méthode. Chaque objet est utilisé pour créer un nouvel objet BackgroundTransferContentPart qui est ensuite placé dans le tableau de 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);
            });

Créer et initialiser l’opération de chargement à parties multiples

Avec notre tableau de contentParts rempli avec tous les objets BackgroundTransferContentPart représentant chaque IStorageFile pour le chargement, nous sommes prêts à appeler CreateUploadAsync à l’aide de l’Uri pour indiquer où la demande sera envoyée.

        // 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);
         }
     };

Redémarrage d’opérations de chargement interrompues

Lors de l’achèvement ou de l’annulation d’une opération UploadOperation, toutes les ressources système associées sont libérées. Toutefois, si votre application est arrêtée avant que l’une de ces situations puisse se produire, toutes les opérations en cours sont suspendues et les ressources associées à chacune d’entre elles persistent. Si ces opérations ne sont pas énumérées et réintroduites dans la session d’application suivante, elles s’arrêteront et resteront présentes dans les ressources d’appareil.

  1. Avant de définir la fonction chargée d’énumérer les opérations persistantes, nous devons créer un tableau pour y stocker les objets UploadOperation que cette fonction renverra :

    var uploadOperations = [];
    
  2. Il nous faut ensuite définir la fonction qui énumère les opérations persistantes et les stocke dans notre tableau. Notez que la méthode load appelée pour réaffecter les rappels vers UploadOperation, si elle persiste après l’arrêt de l’application, se trouve dans la classe UploadOp définie plus loin dans cette section.

    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);
            }
        }
    };
    

Téléchargement de fichiers

Lorsque vous faites appel à la fonctionnalité de transfert en arrière-plan, chaque téléchargement qui en résulte existe sous la forme d’une opération DownloadOperation qui dévoile de nombreuses méthodes de contrôle servant à suspendre, reprendre, redémarrer et annuler l’opération. Les événements d’application (par exemple, une suspension ou un arrêt) et les changements de connectivité sont gérés automatiquement par le système pour chaque opération DownloadOperation. Les téléchargements se poursuivent lors des périodes de suspension des applications et perdurent après l’arrêt des applications. Dans le cadre des scénarios de réseau mobile, la propriété CostPolicy peut être définie pour indiquer si oui ou non votre application entamera ou poursuivra un téléchargement tandis qu’une connexion réseau limitée est utilisée pour la connectivité Internet.

Si vous téléchargez peu de ressources et si l’opération est censée se terminer rapidement, utilisez les API HttpClient à la place du transfert en arrière-plan.

Les exemples qui suivent vous guident tout au long du processus de création et d’initialisation d’un téléchargement de base et décrivent comment énumérer des opérations de chargement issues d’une session d’application précédente.

Configurer et démarrer un téléchargement de fichier à l’aide de la fonctionnalité de transfert en arrière-plan

L’exemple qui suit montre comment des chaînes représentant un URI et un nom de fichier peuvent être utilisées pour créer un objet Uri et le StorageFile qui contiendra la ressource demandée. Dans cet exemple, le nouveau fichier est automatiquement placé à un emplacement prédéfini. La classe FileSavePicker peut également servir aux utilisateurs pour indiquer où enregistrer le fichier sur l’appareil. Notez que la méthode load appelée pour réaffecter les rappels vers DownloadOperation, si elle persiste après l’arrêt de l’application, se trouve dans la classe DownloadOp définie plus loin dans cette section.

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);
        }
    };
}

Notez les appels de méthode asynchrone définis à l’aide de promesses JavaScript. Examinons la ligne 17 du dernier échantillon de code :

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

L’appel de méthode asynchrone est suivi d’une instruction then indiquant les méthodes, définies par l’application, qui sont appelées lorsqu’un résultat de l’appel de méthode asynchrone est retourné. Pour plus d’informations sur ce modèle de programmation, voir Programmation asynchrone en JavaScript à l’aide de promesses.

Ajout de méthodes de contrôle des opérations supplémentaires

Le niveau de contrôle peut être augmenté en implémentant des méthodes DownloadOperation supplémentaires. Par exemple, en intégrant le code suivant à l’exemple ci-dessus, nous pouvons inclure la possibilité d’annuler l’opération.

// 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);
    }
};

Énumération des opérations persistantes au démarrage

Lors de l’achèvement ou de l’annulation d’une opération DownloadOperation, toutes les ressources système associées sont libérées. Toutefois, si votre application est arrêtée avant que l’un de ces événements ne se produise, les téléchargements sont suspendus et persistent en arrière-plan. Les exemples qui suivent expliquent comment réintroduire des téléchargements persistants dans une nouvelle session d’application.

  1. Avant de définir la fonction chargée d’énumérer les opérations persistantes, nous devons créer un tableau pour y stocker les objets DownloadOperation que cette fonction renverra :

    var downloadOps = [];
    
  2. Il nous faut ensuite définir la fonction qui énumère les opérations persistantes et les stocke dans notre tableau. Notez que la méthode load appelée pour réaffecter les rappels pour une opération DownloadOperation persistante se trouve dans l’exemple DownloadOp défini plus loin dans cette section.

    // 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. Vous pouvez désormais utiliser la liste remplie pour redémarrer des opérations en attente.

Post-traitement

Une nouvelle fonctionnalité dans Windows 10 est la possibilité d’exécuter un code d’application à la fin d’un transfert en arrière-plan, même lorsque l’application n’est pas en cours d’exécution. Par exemple, votre application pourrait mettre à jour une liste de films disponibles à l’issue du téléchargement d’un film, au lieu de rechercher la présence de nouveaux films à chaque démarrage. Elle pourrait également gérer un transfert de fichier ayant échoué en réessayant via un serveur ou un port différent. Le post-traitement est appelé pour tous les transferts, réussis ou non. Vous pouvez donc l’utiliser pour implémenter une logique personnalisée de gestion des erreurs et de nouvelle tentative.

Un post-traitement utilise l’infrastructure de tâche en arrière-plan existante. Vous créez une tâche en arrière-plan et l’associez à vos transferts avant de les démarrer. Les transferts sont ensuite exécutés en arrière-plan et, quand ils sont terminés, votre tâche en arrière-plan est appelée pour effectuer le post-traitement.

Un post-traitement utilise une nouvelle classe, BackgroundTransferCompletionGroup. Cette classe est semblable à la classe BackgroundTransferGroup existante, dans la mesure où elle vous permet de regrouper des transferts en arrière-plan. Toutefois, la classe BackgroundTransferCompletionGroup ajoute la possibilité de désigner une tâche en arrière-plan pour s’exécuter une fois le transfert terminé.

Pour initier un transfert en arrière-plan avec post-traitement, procédez comme suit.

  1. Créez un objet BackgroundTransferCompletionGroup. Créez ensuite un objet BackgroundTaskBuilder. Définissez la propriété Trigger de l’objet générateur sur l’objet groupe d’achèvement, et la propriété TaskEntryPoint du générateur sur le point d’entrée de la tâche en arrière-plan qui doit s’exécuter à la fin du transfert. Pour finir, appelez la méthode BackgroundTaskBuilder.Register pour inscrire votre tâche en arrière-plan. Notez que de nombreux groupes d’achèvement peuvent partager un point d’entrée de tâche en arrière-plan, mais que vous ne pouvez avoir qu’un seul groupe d’achèvement par inscription de tâche en arrière-plan.
var completionGroup = new BackgroundTransferCompletionGroup();
BackgroundTaskBuilder builder = new BackgroundTaskBuilder();

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

BackgroundTaskRegistration downloadProcessingTask = builder.Register();
  1. Vous associez ensuite les transferts en arrière-plan au groupe d’achèvement. Une fois tous les transferts créés, activez le groupe d’achèvement.
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. Le code de la tâche en arrière-plan extrait la liste d’opérations des détails du déclencheur. Votre code peut alors inspecter les détails de chaque opération et effectuer un post-traitement approprié pour chaque opération.
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
    }
}

La tâche de post-traitement est une tâche en arrière-plan normale. Elle fait partie du pool de toutes les tâches en arrière-plan, et est soumise à la même stratégie de gestion des ressources que toutes les tâches en arrière-plan.

Notez également que le post-traitement ne remplace pas les gestionnaires d’achèvement au premier plan. Si votre application définit un gestionnaire d’achèvement au premier plan et s’exécute lorsque le transfert de fichiers se termine, votre gestionnaire d’achèvement au premier plan et votre gestionnaire d’achèvement en arrière-plan sont appelés. L’ordre dans lequel les tâches au premier plan et en arrière-plan sont appelées n’est pas garanti. Si vous définissez les deux, vous devez vous assurer que les deux tâches fonctionneront correctement et n’interféreront pas entre elles en cas d’exécution simultanée.

Délais d’expiration des requêtes

Il existe deux cas principaux de délai de connexion à prendre en considération.

  • Lorsque vous établissez une nouvelle connexion pour un transfert, la demande de connexion est annulée si la connexion n’est pas établie dans un délai de cinq minutes.

  • Une fois la connexion établie, un message de requête HTTP qui n’a reçu aucune réponse au bout de deux minutes est annulé.

Réponse Quel que soit le scénario, la fonctionnalité de transfert en arrière-plan part du principe qu’aucune connectivité Internet n’existe et tente jusqu’à trois fois de soumettre automatiquement une demande. Si aucune connectivité Internet n’est décelée, les demandes supplémentaires attendront jusqu’à ce qu’elle le soit.

Recommandations en matière de débogage

L’arrêt d’une session de débogage dans Microsoft Visual Studio est comparable à la fermeture de votre application ; les chargements PUT sont mis en pause et les chargements POST sont arrêtés. Même pendant le débogage, votre application doit énumérer, puis redémarrer ou annuler les chargements persistants. Par exemple, votre application peut annuler l’énumération des opérations de chargement persistantes, au démarrage, si les opérations précédentes n’ont pas d’intérêt pour cette session de débogage.

Vous pouvez faire en sorte que votre application annule l’énumération des opérations de téléchargement/chargement au démarrage durant une session de débogage, si les opérations précédentes n’ont pas d’intérêt pour cette session de débogage. Notez que s’il existe des mises à jour du projet Visual Studio, par exemple des modifications du manifeste de l’application, et si l’application est désinstallée et redéployée, GetCurrentUploadsAsync ne peut pas énumérer les opérations créées à l’aide du déploiement d’application précédent.

Quand vous utilisez le transfert en arrière-plan durant le développement, il arrive que les caches internes des opérations de transfert actives et terminées se désynchronisent. Cela peut entraîner l’incapacité à démarrer de nouvelles opérations de transfert ou à interagir avec les opérations et les objets BackgroundTransferGroup existants. Dans certains cas, toute tentative d’interaction avec des opérations existantes peut déclencher un blocage. Cela peut se produire si la propriété TransferBehavior a la valeur Parallel. Ce problème ne se produit que dans certains scénarios de développement et n’est pas applicable à l’utilisateur final de votre application.

Quatre scénarios d’utilisation de Visual Studio peuvent provoquer ce problème.

  • Vous créez un projet avec le même nom d’application qu’un projet existant, mais dans un autre langage (en passant du C++ au C#, par exemple).
  • Vous modifiez l’architecture cible (en passant de l’architecture x86 à x64, par exemple) dans un projet existant.
  • Vous modifiez la culture (en passant de la culture neutre à fr-FR, par exemple) dans un projet existant.
  • Vous ajoutez ou supprimez une fonctionnalité du manifeste du package (en ajoutant l’authentification en entreprise, par exemple) dans un projet existant.

La maintenance régulière de l’application, notamment les mises à jour du manifeste qui entraînent l’ajout ou la suppression de fonctionnalités, ne déclenche pas ce problème pour les déploiements de votre application destinés à l’utilisateur final. Pour contourner ce problème, désinstallez complètement toutes les versions de l’application, puis redéployez-la en utilisant le nouveau langage, la nouvelle architecture, la nouvelle culture ou la nouvelle fonctionnalité. Vous pouvez l’effectuer via l’écran de démarrage ou à l’aide de PowerShell et de l’applet de commande Remove-AppxPackage.

Exceptions dans Windows.Networking.BackgroundTransfer

Une exception est levée quand une chaîne d’URI non valide est transmise au constructeur pour l’objet Windows.Foundation.Uri.

.NET : le type Windows.Foundation.Uri apparaît en tant que System.Uri en C# et VB.

En C# et Visual Basic, cette erreur peut être évitée en utilisant la classe System.Uri dans .NET 4.5 et l’une des méthodes System.Uri.TryCreate pour tester la chaîne envoyée par l’utilisateur de l’application avant la construction de l’URI.

En C++, aucune méthode ne permet d’essayer et d’analyser une chaîne passée à un URI. Si une application obtient une entrée de l’utilisateur pour la classe Windows.Foundation.Uri, le constructeur doit se trouver dans un bloc try/catch. Si une exception est levée, l’application peut notifier l’utilisateur et demander un nouveau nom d’hôte.

L’espace de noms Windows.Networking.backgroundTransfer propose des méthodes d’assistance pratiques et utilise des énumérations dans l’espace de noms Windows.Networking.Sockets pour la gestion des erreurs. Ceci peut s’avérer utile pour gérer différemment certaines exceptions réseau dans votre application.

Une erreur rencontrée sur une méthode asynchrone dans l’espace de noms Windows.Networking.backgroundTransfer est retournée en tant que valeur HRESULT. La méthode BackgroundTransferError.GetStatus sert à convertir une erreur réseau résultant d’une opération de transfert en arrière-plan en valeur d’énumération WebErrorStatus. La plupart des valeurs d’énumération WebErrorStatus correspondent à une erreur retournée par l’opération cliente HTTP ou FTP native. Une application peut filtrer sur des valeurs d’énumération WebErrorStatus spécifiques pour modifier son comportement en fonction de la cause de l’exception.

Pour les erreurs de validation de paramètre, une application peut également utiliser la valeur HRESULT à partir de l’exception pour obtenir des informations plus détaillées sur l’erreur à l’origine de l’exception. Les valeurs HRESULT possibles sont répertoriées dans le fichier d’en-tête Winerror.h. Pour la plupart des erreurs de validation de paramètre, la valeur HRESULT renvoyée est E\_INVALIDARG.

API importantes