Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Use la API de transferencia en segundo plano para copiar archivos de forma confiable a través de la red. La API de transferencia en segundo plano proporciona características avanzadas de carga y descarga que se ejecutan en segundo plano durante la suspensión de la aplicación y persisten más allá de la finalización de la aplicación. La API supervisa el estado de red y suspende y reanuda automáticamente las transferencias cuando se pierde la conectividad, y las transferencias también son compatibles con el sentido de los datos y el reconocimiento de la batería, lo que significa que la actividad de descarga se ajusta en función de la conectividad actual y el estado de la batería del dispositivo. La API es ideal para cargar y descargar archivos grandes mediante HTTP(S). También se admite FTP, pero solo para descargas.
Note
Las Windows.Networking.BackgroundTransfer API son api de Windows Runtime (WinRT) que funcionan en aplicaciones de escritorio de WinUI 3 (SDK de Aplicaciones para Windows), así como en aplicaciones para UWP. Las transferencias en segundo plano requieren la identidad del paquete; Las aplicaciones sin empaquetar no pueden usar esta API.
La transferencia en segundo plano se ejecuta por separado de la aplicación de llamada y está diseñada principalmente para operaciones de transferencia a largo plazo para recursos como vídeo, música y imágenes grandes. En estos escenarios, el uso de la transferencia en segundo plano es esencial porque las descargas continúan progresando incluso cuando la aplicación está suspendida.
Si va a descargar recursos pequeños que probablemente se completen rápidamente, debe usar las API httpClient en lugar de la transferencia en segundo plano.
Uso de Windows.Networking.BackgroundTransfer
¿Cómo funciona la función de transferencia en segundo plano?
Cuando una aplicación usa La transferencia en segundo plano para iniciar una transferencia, la solicitud se configura e inicializa mediante los objetos de clase BackgroundDownloader o BackgroundUploader . El sistema controla individualmente cada operación de transferencia y se separa de la aplicación que realiza la llamada. La información de progreso está disponible si quieres proporcionar el estado al usuario en la interfaz de usuario de la aplicación y la aplicación puede pausar, reanudar, cancelar o incluso leer de los datos mientras se produce la transferencia. La forma en que el sistema controla las transferencias promueve el uso de energía inteligente y evita problemas que pueden surgir cuando una aplicación conectada encuentra eventos como la suspensión de la aplicación, la terminación o los cambios repentinos de estado de red.
Note
Debido a restricciones de recursos por aplicación, una aplicación no debe tener más de 200 transferencias (DownloadOperations + UploadOperations) en un momento dado. Superar ese límite puede dejar la cola de transferencia de la aplicación en un estado irrecuperable.
Cuando se inicia una aplicación, debe llamar a AttachAsync en todos los objetos DownloadOperation y UploadOperation existentes. Si no lo hace, se producirá la pérdida de transferencias ya completadas y, finalmente, hará que el uso de la característica de transferencia en segundo plano sea inútil.
Realización de solicitudes de archivos autenticadas con transferencia en segundo plano
La transferencia en segundo plano proporciona métodos que admiten credenciales básicas de servidor y proxy, cookies y el uso de encabezados HTTP personalizados (a través de SetRequestHeader) para cada operación de transferencia.
¿Cómo se adapta esta característica a los cambios de estado de red o apagados inesperados?
La característica Transferencia en segundo plano mantiene una experiencia coherente para cada operación de transferencia cuando se producen cambios de estado de red, aprovechando de forma inteligente la información de estado del plan de datos del operador y la conectividad proporcionada por la característica conectividad . Para definir el comportamiento de diferentes escenarios de red, una aplicación establece una directiva de costo para cada operación mediante valores definidos por BackgroundTransferCostPolicy.
Por ejemplo, la directiva de costo definida para una operación puede indicar que la operación debe pausarse automáticamente cuando el dispositivo usa una red de uso medido. La transferencia se reanuda automáticamente (o se reinicia) cuando se ha establecido una conexión a una red "sin restricciones". Para obtener más información sobre cómo se definen las redes por costo, consulte NetworkCostType.
Aunque la característica Transferencia en segundo plano tiene sus propios mecanismos para controlar los cambios de estado de red, hay otras consideraciones generales de conectividad para las aplicaciones conectadas a la red. Use las API de Windows.Networking.Connectivity para supervisar el estado de la conexión y la información sobre costes.
Note
En el caso de las aplicaciones que se ejecutan en dispositivos móviles, hay características que permiten al usuario supervisar y restringir la cantidad de datos que se transfieren en función del tipo de conexión, el estado de itinerancia y el plan de datos del usuario. Debido a esto, las transferencias en segundo plano pueden pausarse en el teléfono incluso cuando backgroundTransferCostPolicy indica que la transferencia debe continuar.
En la tabla siguiente se indica cuándo se permiten transferencias en segundo plano en el teléfono para cada valor BackgroundTransferCostPolicy , según el estado actual del teléfono. Puede usar la clase ConnectionCost para determinar el estado actual del teléfono.
| Estado del dispositivo | Solo sin restricciones | Valor predeterminado | Siempre |
|---|---|---|---|
| Conectado a WiFi | Permitir | Permitir | Permitir |
| Conexión de uso medido, sin roaming, con límite de datos, con seguimiento para permanecer por debajo del límite | Denegar | Permitir | Permitir |
| Conexión de uso medido, sin roaming, con límite de datos, con seguimiento para superar el límite | Denegar | Denegar | Permitir |
| Conexión de uso medido, roaming, con límite de datos | Denegar | Denegar | Permitir |
| Conexión de uso medido, por encima del límite de datos. Este estado solo se produce cuando el usuario habilita "Restringir datos en segundo plano en la interfaz de usuario de Data Sense. | Denegar | Denegar | Denegar |
Carga de archivos
Al usar la transferencia en segundo plano, la carga existe como una UploadOperation que expone varios métodos de control que se usan para reiniciar o cancelar la operación. Los eventos de aplicación (por ejemplo, suspensión o finalización) y los cambios de conectividad se controlan automáticamente por el sistema por UploadOperation; Las cargas continuarán durante los períodos de suspensión de la aplicación o pausarán y persistirán más allá de la terminación de la aplicación. Además, establecer la propiedad CostPolicy indicará si la aplicación iniciará cargas mientras se usa una red de uso medido para la conectividad a Internet.
Los ejemplos siguientes le guiarán por la creación e inicialización de una carga básica y cómo enumerar y volver a introducir operaciones persistentes desde una sesión de aplicación anterior.
Carga de un único archivo
La creación de una carga de archivos comienza con BackgroundUploader. Esta clase se usa para proporcionar los métodos que permiten a la aplicación configurar la carga antes de crear la uploadoperation resultante. En el ejemplo siguiente se muestra cómo hacerlo con los objetos URI y StorageFile necesarios.
Identificar el archivo y el destino de la carga
Antes de poder comenzar a crear una UploadOperation, primero debemos identificar el URI de la ubicación a la que se cargará el archivo y el archivo que se cargará. En el ejemplo siguiente, el valor uriString se rellena mediante una cadena de la entrada de la interfaz de usuario y el valor de archivo mediante el objeto StorageFile devuelto por una operación 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);
});
}
Creación e inicialización de la operación de carga
En el paso anterior, los valores uriString y file se pasan a una instancia de nuestro ejemplo siguiente, UploadOp, donde se usan para configurar e iniciar la nueva operación de carga. En primer lugar, uriString se analiza para crear el objeto URI necesario.
A continuación, backgroundUploader usa las propiedades del storageFile proporcionado (archivo) para rellenar el encabezado de solicitud y establecer la propiedad SourceFile con el objeto StorageFile. A continuación, se llama al método SetRequestHeader para insertar el nombre de archivo, proporcionado como una cadena y la propiedad StorageFile.Name .
Por último, BackgroundUploader crea UploadOperation (carga).
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);
}
};
}
Tenga en cuenta los métodos asincrónicos definidos mediante promesas de JavaScript. Mirando una línea del último ejemplo:
promise = upload.startAsync().then(complete, error, progress);
La llamada al método asincrónico va seguida de una then instrucción que indica los métodos definidos por la aplicación, a los que se llama cuando se devuelve un resultado de la llamada al método asincrónico. Para obtener más información sobre este patrón de programación, consulte Programación asincrónica en JavaScript con promesas.
Carga de varios archivos
Identificar los archivos y el destino de la carga
En un escenario que implica varios archivos transferidos con una sola UploadOperation, el proceso comienza como lo hace normalmente proporcionando primero el URI de destino necesario y la información del archivo local. De forma similar al ejemplo de la sección anterior, el URI se proporciona como una cadena por parte del usuario final y FileOpenPicker se puede usar para proporcionar la capacidad de indicar archivos a través de la interfaz de usuario. Sin embargo, en este escenario, la aplicación debe llamar al método PickMultipleFilesAsync para habilitar la selección de varios archivos a través de la interfaz de usuario.
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);
});
}
Creación de objetos para los parámetros proporcionados
En los dos ejemplos siguientes se usa código contenido en un único método de ejemplo, startMultipart, al que se llamó al final del último paso. Con fines didácticos, el código del método que crea una matriz de objetos BackgroundTransferContentPart se ha separado del código que crea el objeto UploadOperation resultante.
En primer lugar, la cadena de URI proporcionada por el usuario se inicializa como un URI. A continuación, la matriz de objetos IStorageFile (archivos) pasados a este método se recorre en iteración, cada objeto se usa para crear un nuevo objeto BackgroundTransferContentPart que, a continuación, se coloca en la matriz 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);
});
Creación e inicialización de la operación de carga de varias partes
Con nuestra matriz contentParts rellenada con todos los objetos BackgroundTransferContentPart que representan cada IStorageFile para la carga, estamos listos para llamar a CreateUploadAsync mediante el URI para indicar dónde se enviará la solicitud.
// 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);
}
};
Reinicio de las operaciones de carga interrumpidas
Al completarse o cancelarse una UploadOperation, se liberan los recursos del sistema asociados. Sin embargo, si la aplicación finaliza antes de que se produzca cualquiera de estas cosas, las operaciones activas se pausan y los recursos asociados a cada uno permanecen ocupados. Si estas operaciones no se enumeran y se vuelven a introducir en la siguiente sesión de la aplicación, no se completarán y seguirán ocupando los recursos del dispositivo.
Antes de definir la función que enumera las operaciones persistentes, es necesario crear una matriz que contenga los objetos UploadOperation que devolverá:
var uploadOperations = [];A continuación, definimos la función que enumera las operaciones persistentes y las almacena en nuestra matriz. Tenga en cuenta que el método load, que se llama para volver a asignar callbacks a UploadOperation en caso de que persista tras el cierre de la aplicación, está en la clase UploadOp que definimos más adelante en esta sección.
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); } } };
Descarga de archivos
Cuando se usa la transferencia en segundo plano, cada descarga existe como downloadOperation que expone una serie de métodos de control que se usan para pausar, reanudar, reiniciar y cancelar la operación. Los eventos de aplicación (por ejemplo, suspensión o finalización) y los cambios de conectividad se controlan automáticamente por el sistema por DownloadOperation; Las descargas continuarán durante los períodos de suspensión de la aplicación o pausarán y persistirán más allá de la finalización de la aplicación. En escenarios de red móvil, establecer la propiedad CostPolicy indicará si la aplicación comenzará o continuará las descargas mientras se usa una red de uso medido para la conectividad a Internet.
Si va a descargar recursos pequeños que probablemente se completen rápidamente, debe usar las API httpClient en lugar de la transferencia en segundo plano.
Los ejemplos siguientes le guiarán por la creación e inicialización de una descarga básica y cómo enumerar y volver a introducir operaciones persistentes desde una sesión de aplicación anterior.
Configuración e inicio de una descarga de archivos de transferencia en segundo plano
En el ejemplo siguiente se muestra cómo se pueden usar cadenas que representan un URI y un nombre de archivo para crear un objeto URI y el StorageFile que contendrá el archivo solicitado. En este ejemplo, el nuevo archivo se coloca automáticamente en una ubicación predefinida. Como alternativa, FileSavePicker se puede usar para permitir a los usuarios indicar dónde guardar el archivo en el dispositivo. Tenga en cuenta que el método load, al que se llama para volver a asignar callbacks a DownloadOperation si persiste tras el cierre de la aplicación, está en la clase DownloadOp definida más adelante en esta sección.
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);
}
};
}
Tenga en cuenta los métodos asincrónicos definidos mediante promesas de JavaScript. Examine la línea 17 del ejemplo de código anterior:
promise = download.startAsync().then(complete, error, progress);
La llamada al método asíncrono va seguida de una cláusula `then` que indica qué métodos, definidos por la aplicación, se invocan cuando se devuelve un resultado de la llamada al método asíncrono. Para obtener más información sobre este patrón de programación, consulte Programación asincrónica en JavaScript con promesas.
Adición de métodos de control de operaciones adicionales
El nivel de control se puede aumentar mediante la implementación de métodos DownloadOperation adicionales. Por ejemplo, agregar el código siguiente al ejemplo anterior presentará la capacidad de cancelar la descarga.
// 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);
}
};
Enumeración de operaciones persistentes en el inicio
Al finalizar o cancelar una downloadOperation, se liberan todos los recursos del sistema asociados. Sin embargo, si la aplicación finaliza antes de que se produzca cualquiera de estos eventos, las descargas se pausarán y conservarán en segundo plano. En los ejemplos siguientes se muestra cómo volver a introducir descargas persistentes en una nueva sesión de aplicación.
Antes de definir la función que enumera las operaciones persistentes, es necesario crear una matriz que contenga los objetos DownloadOperation que devolverá:
var downloadOps = [];A continuación, definimos la función que enumera las operaciones persistentes y las almacena en nuestra matriz. Tenga en cuenta que el método load al que se llama para volver a asignar callbacks a una DownloadOperation persistida se define en el ejemplo DownloadOp que presentamos más adelante en esta sección.
// 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); } });Ahora puede usar la lista rellenada para reiniciar las operaciones pendientes.
Posprocesamiento
Una nueva característica de Windows 10 es la capacidad de ejecutar código de aplicación al finalizar una transferencia en segundo plano incluso cuando la aplicación no se está ejecutando. Por ejemplo, es posible que la aplicación quiera actualizar una lista de películas disponibles después de que una película haya terminado de descargarse, en lugar de que la aplicación busque nuevas películas cada vez que se inicie. O bien, es posible que la aplicación quiera controlar una transferencia de archivos con errores intentando usar de nuevo un servidor o puerto diferente. El procesamiento posterior se invoca para las transferencias correctas y con errores, por lo que puede usarla para implementar la lógica personalizada de control de errores y reintento.
El posprocesamiento usa la infraestructura de tareas en segundo plano existente. Creas una tarea en segundo plano y la asocias con tus transferencias antes de iniciarlas. Las transferencias se ejecutan en segundo plano y, cuando se completan, se llama a la tarea en segundo plano para realizar el procesamiento posterior.
El procesamiento posterior usa una nueva clase BackgroundTransferCompletionGroup. Esta clase es similar a backgroundTransferGroup existente en que permite agrupar las transferencias en segundo plano, pero BackgroundTransferCompletionGroup agrega la capacidad de designar una tarea en segundo plano que se ejecutará cuando se complete la transferencia.
Se inicia una transferencia en segundo plano con posprocesamiento de la siguiente manera.
- Cree un objeto BackgroundTransferCompletionGroup . A continuación, cree un objeto BackgroundTaskBuilder . Asigne la propiedad Trigger del objeto builder al objeto de grupo de finalización y la propiedad TaskEntryPoint del objeto builder al punto de entrada de la tarea en segundo plano que debe ejecutarse cuando se complete la transferencia. Por último, llame al método BackgroundTaskBuilder.Register para registrar la tarea en segundo plano. Ten en cuenta que muchos de los grupos de finalización pueden compartir un punto de entrada de tarea en segundo plano, pero solo puedes tener un grupo de finalización por registro de tareas en segundo plano.
var completionGroup = new BackgroundTransferCompletionGroup();
BackgroundTaskBuilder builder = new BackgroundTaskBuilder();
builder.Name = "MyDownloadProcessingTask";
builder.SetTrigger(completionGroup.Trigger);
builder.TaskEntryPoint = "Tasks.BackgroundDownloadProcessingTask";
BackgroundTaskRegistration downloadProcessingTask = builder.Register();
- A continuación, asocia transferencias en segundo plano con el grupo de finalización. Una vez creadas todas las transferencias, habilite el grupo de finalización.
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();
- El código de la tarea en segundo plano extrae la lista de operaciones de los detalles del desencadenador y, a continuación, el código puede inspeccionar los detalles de cada operación y realizar el procesamiento posterior adecuado para cada operación.
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 tarea posterior al procesamiento es una tarea en segundo plano normal. Forma parte del grupo de todas las tareas en segundo plano y está sujeto a la misma directiva de administración de recursos que todas las tareas en segundo plano.
Además, tenga en cuenta que el posprocesamiento no reemplaza a los controladores de finalización en primer plano. Si la aplicación define un controlador de finalización en primer plano y la aplicación se ejecuta cuando se completa la transferencia de archivos, se llamará tanto al controlador de finalización en primer plano como al controlador de finalización en segundo plano. No se garantiza el orden en que se ejecutan las tareas en primer plano y las de segundo plano. Si define ambos, debe asegurarse de que las dos tareas funcionarán correctamente y no interferirán entre sí si se ejecutan simultáneamente.
Solicitud de tiempos de expiración
Hay dos escenarios principales de tiempo de espera de conexión que se tienen en cuenta:
Al establecer una nueva conexión para una transferencia, la solicitud de conexión se anula si no se establece en un plazo de cinco minutos.
Una vez establecida una conexión, se anula un mensaje de solicitud HTTP que no ha recibido una respuesta en dos minutos.
Nota En cualquier escenario, suponiendo que haya conectividad a Internet, la transferencia en segundo plano reintentará una solicitud hasta tres veces automáticamente. En caso de que no se detecte conectividad a Internet, las solicitudes adicionales esperarán hasta que sea.
Guía de depuración
Detener una sesión de depuración en Microsoft Visual Studio es comparable a cerrar tu aplicación; las cargas PUT se pausan y las cargas POST se interrumpen. Incluso durante la depuración, tu aplicación debe enumerar y reiniciar o cancelar todas las cargas que persisten. Por ejemplo, puede hacer que su aplicación cancele las operaciones de carga persistentes enumeradas al iniciarse la aplicación si no le interesan las operaciones anteriores de esa sesión de depuración.
Al enumerar descargas o cargas en el inicio de la aplicación durante una sesión de depuración, puede hacer que la aplicación las cancele si no hay ningún interés en las operaciones anteriores para esa sesión de depuración. Tenga en cuenta que si hay Visual Studio actualizaciones del proyecto, como los cambios en el manifiesto de la aplicación, y la aplicación se desinstala y se vuelve a implementar, GetCurrentUploadsAsync no puede enumerar las operaciones creadas con la implementación de la aplicación anterior.
Al usar la transferencia en segundo plano durante el desarrollo, puede encontrarse en una situación en la que las memorias caché internas de las operaciones de transferencia activas y completadas pueden salir de la sincronización. Esto puede dar lugar a la incapacidad de iniciar nuevas operaciones de transferencia o interactuar con las operaciones existentes y los objetos BackgroundTransferGroup . En algunos casos, intentar interactuar con operaciones ya existentes puede producir un bloqueo. Este resultado puede producirse si la propiedad TransferBehavior está establecida en Parallel. Este problema solo se produce en determinados escenarios durante el desarrollo y no es aplicable a los usuarios finales de la aplicación.
Cuatro escenarios que usan Visual Studio pueden provocar este problema.
- Cree un nuevo proyecto con el mismo nombre de aplicación que un proyecto existente, pero otro lenguaje (de C++ a C#, por ejemplo).
- Puede cambiar la arquitectura de destino (de x86 a x64, por ejemplo) en un proyecto existente.
- Puede cambiar la referencia cultural (de neutral a en-US, por ejemplo) en un proyecto existente.
- Agregue o quite una funcionalidad en el manifiesto del paquete (agregando autenticación empresarial, por ejemplo) en un proyecto existente.
El mantenimiento de aplicaciones normal, incluidas las actualizaciones de manifiesto que agregan o quitan funcionalidades, no desencadenan este problema en las implementaciones de usuario final de la aplicación. Para solucionar este problema, desinstale completamente todas las versiones de la aplicación y vuelva a implementar con el nuevo lenguaje, arquitectura, referencia cultural o funcionalidad. Esto se puede hacer a través de la pantalla Inicio o mediante PowerShell y el cmdlet Remove-AppxPackage .
Excepciones en Windows.Networking.BackgroundTransfer
Se produce una excepción cuando se pasa una cadena no válida para un identificador uniforme de recursos (URI) al constructor del Windows. Objeto Foundation.Uri.
.NET: El tipo Windows.Foundation.Uri aparece como System.Uri en C# y VB.
En C# y Visual Basic, este error se puede evitar mediante el uso de la clase System.Uri en el .NET 4.5 y uno de los métodos System.Uri.TryCreate para probar la cadena recibida del usuario de la aplicación antes de que se construya el URI.
En C++, no hay ningún método para probar y analizar una cadena en un URI. Si una aplicación recibe información del usuario relativa a Windows.Foundation.Uri, el constructor debe estar en un bloque Try/Catch. Si se produce una excepción, la aplicación puede notificar al usuario y solicitar un nuevo nombre de host.
El espacio de nombres Windows.Networking.backgroundTransfer dispone de prácticos métodos auxiliares y usa enumeraciones del espacio de nombres Windows.Networking.Sockets para controlar los errores. Esto puede ser útil para controlar excepciones de red específicas de forma diferente en la aplicación.
Un error detectado en un método asíncrono del espacio de nombres Windows.Networking.backgroundTransfer se devuelve como un valor HRESULT. El método BackgroundTransferError.GetStatus se usa para convertir un error de red de una operación de transferencia en segundo plano a un valor de enumeración WebErrorStatus . La mayoría de los valores de enumeración WebErrorStatus corresponden a un error devuelto por la operación de cliente HTTP o FTP nativa. Una aplicación puede filtrar por valores específicos de enumeración WebErrorStatus para modificar el comportamiento de la aplicación en función de la causa de la excepción.
En el caso de los errores de validación de parámetros, una aplicación también puede usar HRESULT de la excepción para obtener información más detallada sobre el error que provocó la excepción. Los posibles valores HRESULT se enumeran en el archivo de encabezado Winerror.h . Para la mayoría de los errores de validación de parámetros, el valor HRESULT devuelto es E_INVALIDARG.