Compartir a través de



Noviembre de 2015

Volumen 30, número 12

Windows 10: Acelere las operaciones de archivos con el Indizador de búsqueda

Por Adam Wilson | Noviembre de 2015

El Indizador de búsqueda ha estado presente en numerosas versiones de Windows hasta la fecha, proporcionando desde vistas de bibliotecas en el Explorador de archivos hasta la barra de direcciones de IE, pasando por la funcionalidad de búsqueda del menú Inicio y de Outlook. Con Windows 10, la capacidad del indizador ha dejado de estar limitada a las máquinas de escritorio para estar disponible para todas las aplicaciones de la Plataforma universal de Windows. Pese a que esta mayor capacidad permite a Cortana realizar mejores búsquedas, la parte más interesante de este avance es, sin duda, la mejora en la interacción de las aplicaciones con el sistema de archivos.

El indizador permite a las aplicaciones realizar operaciones más interesantes como, por ejemplo, ordenar y agrupar archivos o realizar un seguimiento de los cambios que se producen en el sistema de archivos. La mayoría de las API del indizador están disponibles para las aplicaciones para UWP a través de los espacios de nombres Windows.Storage y Windows.Storage.Search. De hecho, las aplicaciones ya usan el indizador para ofrecer a sus usuarios experiencias de calidad. En este artículo, analizaremos cómo se puede usar el indizador para tareas como, por ejemplo, realizar un seguimiento de los cambios que se producen en el sistema de archivos, representar vistas con rapidez o proporcionar sugerencias básicas de mejora de las consultas de las aplicaciones.

Acceso rápido a los archivos y los metadatos

La mayoría de los dispositivos de usuario contienen cientos o incluso miles de archivos multimedia de fotografías o canciones favoritas del usuario. Las aplicaciones capaces de iterar rápidamente con los archivos del dispositivo y ofrecer atractivas interacciones con el contenido de dichos archivos se encuentran entre las aplicaciones más populares de las distintas plataformas. UWP ofrece un conjunto de clases que pueden usarse para tener acceso a los archivos de cualquier dispositivo, sin importar cuál sea el factor de forma.

El espacio de nombres Windows.Storage incluye las clases básicas para el acceso a archivos y carpetas, así como las operaciones básicas que realizan la mayoría de las aplicaciones con ellos. Sin embargo, si su aplicación necesita acceso a numerosos archivos o metadatos, estas clases no ofrecen las características de rendimiento que necesitan los clientes.

Por ejemplo, la llamada a StorageFolder.GetFilesAsync es una fórmula para el desastre si no se controla la carpeta que se va a enumerar. Los usuarios pueden guardar millones de archivos en un único directorio. Por ello, si intentamos crear objetos StorageFile para cada uno de ellos, conseguiremos que la aplicación se quede sin memoria rápidamente. Incluso en los casos menos extremos, la llamada devolverá el resultado de manera muy lenta porque el sistema tendrá que crear miles de identificadores de archivos y calcular las referencias de nuevo en el contenedor de la aplicación. Para evitar este problema en las aplicaciones, el sistema ofrece las clases StorageFileQueryResults y StorageFolderQueryResults.

StorageFileQueryResults es la clase que debe usarse siempre para programar una aplicación que vaya a controlar más archivos de lo normal. No solo permite enumerar y modificar con claridad los resultados de consultas de búsquedas complejas, sino que, gracias a que la API trata las solicitudes de enumeración como consultas “*,”, también funciona para casos más comunes.

Usar el indizador cuando está disponible es el primer paso para agilizar las aplicaciones. Dichas por el administrador del programa del indizador, estas palabras pueden sonar como un llamamiento en beneficio propio para seguir teniendo trabajo; sin embargo, existe una razón lógica para ello. Los objetos StorageFile y StorageFolder han sido diseñados para el indizador. Las propiedades que se almacenan en la caché del objeto pueden recuperarse rápidamente desde el indizador. Si no se va a usar el indizador, el sistema tendrá que buscar valores en el disco y el registro. Esto implica una intensa actividad de E/S y crea problemas de rendimiento tanto para la aplicación como para el sistema.

Para asegurarse de que se usará el indizador, podemos crear un objeto Query­Options y establecer la propiedad QueryOptions.IndexerOption para que use solo el indizador:

QueryOptions options = new QueryOptions();
options.IndexerOption = IndexerOption.OnlyUseIndexer;

O bien para que use el indizador cuando no esté disponible:

options.IndexerOption = IndexerOption.UseIndexerWhenAvailable;

Se recomienda usar IndexerOption.Use­IndexerWhenAvailable cuando la lentitud de las operaciones de archivos no bloquee la aplicación ni paralice la experiencia del usuario. Esta clase intentará usar el indizador para enumerar los archivos, aunque ralentizará mucho las operaciones de disco. Se recomienda usar la clase IndexerOption.OnlyUseIndexer cuando es preferible no obtener ningún resultado que esperar a que finalicen las operaciones de archivo. El sistema devolverá cero resultados si el indizador está deshabilitado, aunque la respuesta será rápida, por lo que las aplicaciones seguirán reaccionando ante las acciones del usuario.

Habrá veces en las que la creación del objeto QueryOptions parezca un poco excesivo para una simple enumeración rápida. En estos casos, no es necesario preocuparse si el indizador está presente. Para los casos en los que podamos controlar el contenido de la carpeta, es preferible llamar a la clase StorageFolder.GetItemsAsync. Se trata de una simple línea de código fácil de programar que ocultará los problemas de rendimiento cuando el directorio contenga pocos archivos.

Otra forma de agilizar la enumeración de archivos consiste en no crear archivos StorageFile o StorageFolder innecesarios. Incluso cuando se use el indizador, la apertura del objeto StorageFile requiere que el sistema cree un controlador de archivo, recopile datos de propiedades y calcule las referencias en el proceso de la aplicación. Esta comunicación entre procesos implica retrasos que pueden evitarse en muchos casos al no crear los objetos en primer lugar.

Es importante tener en cuenta que el objeto StorageFileQueryResult respaldado por el indizador no crea ningún objeto StorageFiles internamente. Estos objetos se crean a petición cuando se solicitan a través de GetFilesAsync. Hasta ese momento, el sistema solo conservará una lista de los archivos en memoria mucho más ligera en comparación.

Para enumerar un elevado número de archivos, se recomienda usar la funcionalidad de procesamiento por lotes para crear páginas de grupos de archivos conforme sean necesarios. De este modo, será posible procesar en segundo plano los archivos a la espera de que se cree el siguiente conjunto. El código de la figura 1 muestra cómo llevar esto a cabo con un ejemplo sencillo.

Figura 1: GetFilesAsync

uint index = 0, stepSize = 10;
IReadOnlyList<StorageFile> files = await queryResult.GetFilesAsync(index, stepSize);
index += 10;          
while (files.Count != 0)
{
  var fileTask = queryResult.GetFilesAsync(index, stepSize).AsTask();
  foreach (StorageFile file in files)
  {
    // Do the background processing here   
  }
  files = await fileTask;
  index += 10;
}

Este es el mismo patrón de código que el usan numerosas aplicaciones de Windows ya existentes. Al variar el tamaño del paso, es posible obtener el número necesario de elementos para disponer de una primera vista dinámica en la aplicación al mismo tiempo que se preparan rápidamente los demás archivos en segundo plano.

La precarga de propiedades es otra manera fácil de agilizar la aplicación, ya que permite que la aplicación notifique al sistema que está interesada en un conjunto determinado de propiedades. El sistema tomará las propiedades del indizador mientras enumera un conjunto de archivos y los almacena en caché en el objeto StorageFile. Esto permite incrementar el rendimiento en comparación con la simple recopilación gradual de propiedades cuando se devuelven los archivos.

Establezca los valores de precarga en el objeto QueryOptions. Existen numerosos escenarios compatibles con el uso de Property­PrefetchOptions; sin embargo, las aplicaciones también pueden personalizar las propiedades solicitadas según los valores admitidos en Windows. El código necesario es bastante simple:

QueryOptions options = new QueryOptions();
options.SetPropertyPrefetch(PropertyPrefetchOptions.ImageProperties,
  new String[] { });

En este caso, la aplicación usa las propiedades de la imagen y no necesita ninguna otra propiedad. Cuando el sistema enumere los resultados de la consulta, almacenará las propiedades de la imagen en la caché para que estén rápidamente disponibles más adelante.

Por último, hay que tener en cuenta que la propiedad debe almacenarse en el índice para que la precarga ofrezca un aumento de rendimiento; de lo contrario, el sistema seguirá necesitando tener acceso al archivo para buscar el valor, lo que resulta mucho más lento en comparación. La página del centro de desarrollo de Microsoft Windows del sistema de propiedades (bit.ly/1LuovhT) tiene toda la información sobre las propiedades disponibles en el Indizador de Windows. Basta con buscar el valor isColumn = true en la descripción de la propiedad, que indicará que la propiedad está disponible para la precarga.

Todas estas mejoras juntas agilizan la ejecución del código. Por poner un ejemplo sencillo, he programado una aplicación que recupera todas las imágenes de mi equipo junto con la altura vertical. Este es el primer paso que deberá realizar toda aplicación de visualización de fotografías para mostrar la colección de fotografías del usuario.

He ejecutado la aplicación tres veces para probar distintos estilos de enumeración de archivos y para mostrar las diferencias que hay entre ellos. Para la primera prueba he usado código Naïve con el indizador habilitado, tal como se muestra en la figura 2. En la segunda prueba usé el código que se muestra en la figura 3, que precarga las propiedades y las páginas en los archivos. Por último, en la tercera prueba, usé la precarga de propiedades y los archivos de paginación, aunque con el indizador deshabilitado. Este código es el mismo que el que se muestra en la figura 3, pero con una línea distinta, tal como se muestra en los comentarios.

Figura 2: Enumeración de una biblioteca con código Naïve

StorageFolder folder = KnownFolders.PicturesLibrary;
QueryOptions options = new QueryOptions(
  CommonFileQuery.OrderByDate, new String[] { ".jpg", ".jpeg", ".png" });          
options.IndexerOption = IndexerOption.OnlyUseIndexer;
StorageFileQueryResult queryResult = folder.CreateFileQueryWithOptions(options);
Stopwatch watch = Stopwatch.StartNew();          
IReadOnlyList<StorageFile> files = await queryResult.GetFilesAsync();
foreach (StorageFile file in files)
{                
  IDictionary<string, object> size =
    await file.Properties.RetrievePropertiesAsync(
    new String[] { "System.Image.VerticalSize" });
  var sizeVal = size["System.Image.VerticalSize"];
}           
watch.Stop();
Debug.WriteLine("Time to run the slow way: " + watch.ElapsedMilliseconds + " ms");

Figura 3: Código optimizado para la numeración de una biblioteca

StorageFolder folder = KnownFolders.PicturesLibrary;
QueryOptions options = new QueryOptions(
  CommonFileQuery.OrderByDate, new String[] { ".jpg", ".jpeg", ".png" });
// Change to DoNotUseIndexer for trial 3
options.IndexerOption = IndexerOption.OnlyUseIndexer;
options.SetPropertyPrefetch(PropertyPrefetchOptions.None, new String[] { "System.Image.VerticalSize" });
StorageFileQueryResult queryResult = folder.CreateFileQueryWithOptions(options);
Stopwatch watch = Stopwatch.StartNew();
uint index = 0, stepSize = 10;
IReadOnlyList<StorageFile> files = await queryResult.GetFilesAsync(index, stepSize);
index += 10;
// Note that I'm paging in the files as described
while (files.Count != 0)
{
  var fileTask = queryResult.GetFilesAsync(index, stepSize).AsTask();
  foreach (StorageFile file in files)
  {
// Put the value into memory to make sure that the system really fetches the property
    IDictionary<string,object> size =
      await file.Properties.RetrievePropertiesAsync(
      new String[] { "System.Image.VerticalSize" });
    var sizeVal = size["System.Image.VerticalSize"];                   
  }
  files = await fileTask;
  index += 10;
}
watch.Stop();
Debug.WriteLine("Time to run: " + watch.ElapsedMilliseconds + " ms");

Si prestamos atención a los resultados con y sin precarga, la diferencia de rendimiento es palpable, tal como se aprecia en la figura 4.

Figura 4: Resultados con y sin precarga

Caso de prueba (2600 imágenes en una máquina de escritorio) Tiempo medio de ejecución de más de 10 muestras
Código Naïve + indizador 9318 ms
Todas las optimizaciones + indizador 5796 ms
Optimizaciones + sin indizador 20 248 ms (48 420 ms en frío)

La aplicación de las optimizaciones sencillas que se detallan aquí permiten casi duplicar el rendimiento del código Naïve. Los patrones también se han probado en situaciones reales. Antes del lanzamiento de cualquier versión de Windows, trabajamos con los equipos de aplicaciones para garantizar el funcionamiento de aplicaciones como, por ejemplo, Fotografías, Groove Música, etc. De ahí es de donde proceden estos patrones: se copian directamente del código de las primeras aplicaciones para UWP de UWP y pueden aplicarse directamente a las aplicaciones.

Seguimiento de cambios en el sistema de archivos

Tal como se muestra aquí, la enumeración de todos los archivos de una ubicación es un proceso que consume numerosos recursos. La mayoría de las veces, los usuarios no estarán interesados en los archivos antiguos. Solo quieren la imagen que están buscando, la canción que acaban de descargar o el documento modificado más recientemente. Para mostrar en primer lugar los archivos más recientes, su aplicación puede realizar un seguimiento de los cambios realizados en el sistema de archivos y buscar fácilmente los archivos creados o modificados más recientemente.

Existen dos maneras de realizar el seguimiento de los cambios que dependen de si su aplicación se ejecuta en segundo plano o en primer plano. Cuando una aplicación se ejecuta en primer plano, puede usar el evento ContentsChanged desde el objeto StorageFileQueryResult para recibir una notificación de los cambios de una consulta determinada. Cuando la aplicación está en segundo plano, puede registrar StorageLibraryContentChangedTrigger para recibir una notificación de los cambios que se realizan. Ambos métodos funcionan como notificaciones de aviso que permiten a las aplicaciones saber si se ha modificado contenido; sin embargo, no incluyen información sobre los archivos que se han modificado.

Para buscar los archivos que se han modificado o creado recientemente, el sistema ofrece la propiedad System.Search.GatherTime. La propiedad se establece para todos los archivos de una ubicación indizada y realiza un seguimiento de la última vez que el indizador detectó una modificación en los archivos. Esta propiedad se actualizará de manera constante en función del reloj del sistema. Sin embargo, las excepciones relacionadas con los cambios de zona horaria, el horario de verano y los cambios manuales de la hora del sistema siguen dependiendo de la confianza depositada en este valor de su aplicación.

El registro de eventos de seguimiento de cambios en primer plano es sencillo. Una vez creado el objeto StorageFileQueryResult que abarca el ámbito de interés para su aplicación, basta con registrar el evento ContentsChanged, tal como se muestra aquí:

StorageFileQueryResult resultSet = photos.CreateFileQueryWithOptions(option);
resultSet.ContentsChanged += resultSet_ContentsChanged;

Este evento se iniciará siempre que haya alguna modificación en el conjunto de resultados. De este modo, la aplicación podrá buscar el archivo o los archivos modificados recientemente.

El seguimiento de los cambios desde un segundo plano es más complejo. Las aplicaciones pueden registrarse para recibir una notificación cuando se produce algún cambio de biblioteca en el dispositivo. Puesto que no es posible usar ámbitos o consultas más complejas, las aplicaciones son las que deben asegurarse de que el cambio es algo que realmente les interesa.

Como dato interesante, el motivo por el que las aplicaciones solo pueden registrarse para recibir notificaciones de los cambios en la biblioteca y no según el tipo de archivo, se debe a la manera en que está diseñado el indizador. El filtrado de consultas según la ubicación de un archivo en el disco es mucho más rápido que realizar una consulta basada en el tipo de archivo. Además, en las pruebas iniciales realizadas, nos dimos cuenta de que esto ralentizaba bastante el rendimiento. Más adelante proporcionará sugerencias de rendimiento; sin embargo, es muy importante recordar lo siguiente: El filtrado de resultados de consultas por ubicación de archivo es mucho más rápido que cualquier otra operación de filtrado.

En la publicación de blog (bit.ly/1iPUVIo) se detallan los pasos que deben seguirse para registrar una tarea en segundo plano con códigos de muestra. Sin embargo, a continuación se ofrecen detalles sobre un par de pasos interesantes. Lo primero que debe hacer la aplicación es crear el desencadenador de segundo plano:

StorageLibrary library =
  await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
StorageLibraryContentChangedTrigger trigger =
  StorageLibraryContentChangedTrigger.Create(library);

El desencadenador se puede crear a partir de una colección de bibliotecas si la aplicación está interesada en realizar un seguimiento de varias ubicaciones. En este caso, la aplicación solo buscará las bibliotecas de imágenes. Este es uno de los escenarios de aplicaciones más comunes. Es necesario asegurarse de que la aplicación tenga la capacidad correcta para poder tener acceso a la biblioteca de cuyos cambios está intentando realizar el seguimiento, ya que, de lo contrario el sistema devolverá una excepción de acceso denegado cuando la aplicación intente crear el objeto StorageLibrary.

En los dispositivos móviles Windows, esto resulta especialmente útil, ya que el sistema garantiza que las nuevas imágenes del dispositivo se escribirán en la ubicación de biblioteca de imágenes. Esta operación se realiza independientemente de las opciones que elija el usuario en la página de configuración al cambiar las carpetas que se incluirán como parte de la biblioteca.

La aplicación debe registrar la tarea en segundo plano mediante Background­ExecutionManager y debe tener la tarea en segundo plano integrada. La tarea en segundo plano puede activarse mientras la aplicación está en primer plano. De este modo, el código debe conocer las posibles condiciones de carrera del acceso al registro o el archivo.

Una vez completado el registro, se llamará la aplicación cada vez que se produzca un cambio en la biblioteca para la que se haya realizado el registro. Esto puede incluir archivos que no resulten de interés para la aplicación o que esta no pueda procesar. En ese caso, la mejor manera de garantizar que el procesamiento en segundo plano no se realiza en vano es con la aplicación de un filtro restrictivo tan pronto como se desencadene la tarea en segundo plano.

La búsqueda de archivos modificados o agregados recientemente es sencilla: basta con realizar una consulta simple al indizador. Solicite todos los archivos con un tiempo de recopilación en un rango que resulte de interés para la aplicación. Si lo desea, también puede usar las mismas características de agrupación y ordenación que las que están disponibles para otras consultas. Tengan en cuenta que el indizador usa internamente la hora zulú. Por lo tanto, es necesario convertir todas las cadenas de hora a la hora zulú antes de usarlas. A continuación se muestra cómo se puede crear una consulta:

QueryOptions options = new QueryOptions();
DateTimeOffset lastSearchTime = DateTimeOffset.UtcNow.AddHours(-1);
// This is the conversion to Zulu time, which is used by the indexer
string timeFilter = "System.Search.GatherTime:>=" +
  lastSearchTime.ToString("yyyy\\-MM\\-dd\\THH\\:mm\\:ss\\Z")
options.ApplicationSearchFilter += timeFilter;

En este caso, la aplicación obtendrá todos los resultados de la última hora. En determinadas aplicaciones, es preferible guardar la hora de la última consulta y usarla en la consulta, aunque se puede usar cualquier DateTimeOffset. Una vez que la aplicación tiene la lista de archivos, podrá enumerarlos tal como se ha visto anteriormente o usar la lista para realizar un seguimiento de los archivos nuevos.

La combinación de los dos métodos de seguimiento de cambios con el tiempo de recopilación permite que las aplicaciones para UWP puedan realizar un seguimiento del sistema de archivos y, de este modo, reaccionar fácilmente ante los cambios que se produzcan en el disco. Pese a que estas API son relativamente nuevas en la historia de Windows, se han usado en aplicaciones integradas en Windows 10 como Fotografías, Groove Música, OneDrive, Cortana y Películas y televisión. Puede estar seguro que al incluir estas API en sus aplicaciones, estará ofreciendo a los usuarios la mejor de las experiencias.

Procedimientos recomendados generales

Hay varias cosas que las aplicaciones que usen el indizador deben tener en cuenta para evitar errores y garantizar un funcionamiento rápido de la aplicación. Las aplicaciones deben evitar las consultas complejas innecesarias en las partes críticas de la aplicación, usar correctamente las enumeraciones de propiedades y estar al tanto de los retrasos de indexación.

El diseño de las consultas puede tener una importante repercusión en su rendimiento. Cuando el indizador ejecuta consultas a su base de datos, algunas consultas son más rápidas que otras debido a la manera en que los datos están almacenados en el disco. El filtrado basado en la ubicación de los archivos es siempre más rápido, ya que permite al indizador eliminar rápidamente grandes partes del índice desde la consulta. Esto reduce el tiempo de E/S y el consumo de recursos del procesador puesto que el número de cadenas que se deben recuperar y comparar durante la búsqueda de coincidencias con los términos de la consulta es menor.

El indizador cuenta con recursos suficientes para controlar las expresiones regulares, aunque hay algunas que pueden ralentizar su funcionamiento. Lo peor que se puede incluir en una consulta de indizador es una búsqueda de sufijos. Esta búsqueda es una consulta de todos los términos que acaban con un valor determinado. Un ejemplo sería la consulta “*tion,” que buscará todos los documentos que contengan palabras acabadas en “tion.” Puesto que el índice se ordena por la primera letra de cada token, no existe forma rápida de buscar términos que coincidan con esta consulta. Por lo tanto, la consulta se ve obligada a descodificar todos los token del índice y compararlos con el término de búsqueda. Este proceso es extremadamente lento.

Las enumeraciones pueden agilizar las consultas, aunque tienen un comportamiento inesperado en las compilaciones internacionales. Todo el que haya compilado alguna vez un sistema de búsqueda sabrá que las comparaciones basadas en enumeraciones son mucho más rápidas que las comparaciones de cadenas. Esto también se cumple con el indizador. Para facilitar la tarea a su aplicación, el sistema de propiedades ofrece varias enumeraciones que permiten filtrar los resultados y mostrar menos elementos antes de iniciar las comparaciones de cadenas. Un ejemplo habitual de ello es el uso del filtro System.Kind para restringir el resultado a solo los archivos que puede controlar la aplicación como, por ejemplo, música o documentos.

No obstante, hay un error común que todo usuario de enumeraciones debe conocer. Si el usuario solo va a buscar archivos de música, en una versión en-us de Windows, bastará con agregar System.Kind:=music a la consulta para que funcione a la perfección para restringir los resultados de búsqueda y agilizar la consulta. Esto también funciona con otros idiomas (posiblemente sea suficiente como para superar las pruebas de internacionalización); sin embargo, no funcionará en los casos en los que el sistema no pueda reconocer “music” como término en inglés y lo analice en el idioma local.

La forma correcta de usar una enumeración como System.Kind es denotar claramente que la aplicación intentará usar el valor como una enumeración y no como término de búsqueda. Esto se realiza con la sintaxis enumeration#value. Por ejemplo, la manera correcta de filtrar solo los resultados de búsqueda sería con la consulta System.Kind:=System.Kind#Music. Esto funciona en todos los idiomas de Windows y filtra los resultados a solo los archivos que el sistema reconoce como música.

Procesar correctamente los caracteres de escape de la sintaxis de consulta avanzada (AQS) puede ayudar a que los usuarios no experimenten problemas de dificultades de reproducción. AQS cuenta con numerosas características que permiten a los usuarios incluir comillas o paréntesis que afectan al procesamiento de la consulta. Esto significa que las aplicaciones deben tener precaución a la hora de procesar los caracteres de escape de los términos de la consulta que incluyan dichos caracteres. Por ejemplo, la búsqueda de Document(8).docx generará un error de análisis y resultados incorrectos. En su lugar, la aplicación debe procesar la secuencia de escape del término de este modo: Document%288%29.docx. Esto devolverá los elementos del índice que coincidan con el término de búsqueda y evitará que el sistema analice los paréntesis como parte de la consulta.

Para obtener información detallada de las características de AQS y de cómo asegurarse de que las consultas son correctas, consulte la documentación que encontrará en bit.ly/1Fhacfl. En este sitio encontrará mucha información de utilidad, incluidos los detalles sobre las sugerencias aquí mencionadas.

Nota sobre los retrasos en la indización: El indexado no es instantáneo. Esto significa que los elementos que aparecen en el índice o las notificaciones basadas en el indizador sufrirán un retraso con respecto a cuándo se escribe el archivo. Con una carga de sistema normal, el retraso será de unos 100 ms: menos de lo que tardan la mayoría de las aplicaciones en consultar al sistema. Por lo tanto, apenas notará ningún retraso. Habrá casos en los que, por ejemplo, el usuario esté migrando miles de archivos en su máquina y el indizador no sea capaz de seguir el ritmo.

Para estos casos, se recomienda que las aplicaciones realicen dos acciones: En primer lugar, deberán mantener abierta una consulta en las ubicaciones del sistema de archivos de mayor interés para la aplicación. Esto suele hacerse creando el objeto StorageFileQueryResult en las ubicaciones del sistema de archivos en las que buscará la aplicación. Cuando el indizador vea que una aplicación tiene una consulta abierta, dará prioridad a dichos ámbitos sobre los demás. Asegúrese de no hacer esto para un ámbito mayor del necesario. El indizador dejará de respetar la interrupción del sistema y las notificaciones activas del usuario para procesar los cambios lo más rápido posible, lo que puede repercutir en el rendimiento del sistema.

La otra recomendación es la de avisar a los usuarios de que el sistema se está poniendo al día con las operaciones de archivos. Algunas aplicaciones como, por ejemplo, Cortana muestran un mensaje en la interfaz de usuario, mientras que otras dejan de realizar consultas complejas y muestran una versión simple de la experiencia. Usted decide qué es lo mejor para su experiencia de aplicación.

Resumen

En este artículo hemos hecho un breve recorrido por las características disponibles para los consumidores del indizador y por las API de Windows Storage disponibles en Windows 10. Para obtener más información sobre cómo usar consultas para pasar contexto sobre la activación de aplicaciones o muestras de código del desencadenador en segundo plano, visite el blog del equipo en bit.ly/1iPUVIo. Trabajamos continuamente con los desarrolladores para garantizar que las API de búsqueda sean útiles. Estaremos encantados de saber si las API funcionan correctamente y si hay alguna característica que desearía agregar.


Adam Wilsones un administrador de programas del equipo de plataforma y ecosistema de desarrolladores de Windows. Adam trabaja en el indizador de Windows y en la confiabilidad de las notificaciones de inserción. Anteriormente, trabajó en las API de almacenamiento para Windows Phone 8.1. Su dirección de correo electrónico de contacto es adwilso@microsoft.com.

Gracias al siguiente experto técnico por su ayuda en la revisión de este artículo: Sami Khoury
Sami Khoury trabaja como ingeniero en el equipo de plataforma y ecosistema de desarrolladores de Windows. Sami dirige el desarrollo del Indizador de Windows.