Cómo: Crear tareas precalculadasHow to: Create Pre-Computed Tasks

Este documento describe cómo utilizar el Task.FromResult método para recuperar los resultados de las operaciones de descarga asincrónica que se mantienen en una memoria caché.This document describes how to use the Task.FromResult method to retrieve the results of asynchronous download operations that are held in a cache. El FromResult método devuelve un terminado Task<TResult> objeto que contiene el valor proporcionado como su Result propiedad.The FromResult method returns a finished Task<TResult> object that holds the provided value as its Result property. Este método es útil cuando se realiza una operación asincrónica que devuelve un objeto Task<TResult> y el resultado de ese objeto Task<TResult> ya se ha calculado.This method is useful when you perform an asynchronous operation that returns a Task<TResult> object, and the result of that Task<TResult> object is already computed.

EjemploExample

En el ejemplo siguiente se descarga cadenas desde la web.The following example downloads strings from the web. Define la DownloadStringAsync método.It defines the DownloadStringAsync method. Este método descargas de cadenas de forma asincrónica desde la web.This method downloads strings from the web asynchronously. Este ejemplo también utiliza un ConcurrentDictionary<TKey,TValue> objeto que se va a almacenar en caché los resultados de las operaciones anteriores.This example also uses a ConcurrentDictionary<TKey,TValue> object to cache the results of previous operations. Si la dirección de entrada se mantiene en esta memoria caché, DownloadStringAsync utiliza la FromResult método para generar un Task<TResult> objeto que contiene el contenido en esa dirección.If the input address is held in this cache, DownloadStringAsync uses the FromResult method to produce a Task<TResult> object that holds the content at that address. En caso contrario, DownloadStringAsync descarga el archivo desde la web y agrega el resultado a la memoria caché.Otherwise, DownloadStringAsync downloads the file from the web and adds the result to the cache.

using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading.Tasks;

// Demonstrates how to use Task<TResult>.FromResult to create a task 
// that holds a pre-computed result.
class CachedDownloads
{
   // Holds the results of download operations.
   static ConcurrentDictionary<string, string> cachedDownloads =
      new ConcurrentDictionary<string, string>();

   // Asynchronously downloads the requested resource as a string.
   public static Task<string> DownloadStringAsync(string address)
   {
      // First try to retrieve the content from cache.
      string content;
      if (cachedDownloads.TryGetValue(address, out content))
      {
         return Task.FromResult<string>(content);
      }

      // If the result was not in the cache, download the 
      // string and add it to the cache.
      return Task.Run(async () =>
      {
         content = await new WebClient().DownloadStringTaskAsync(address);
         cachedDownloads.TryAdd(address, content);
         return content;
      });
   }

   static void Main(string[] args)
   {
      // The URLs to download.
      string[] urls = new string[]
      {
         "http://msdn.microsoft.com",
         "http://www.contoso.com",
         "http://www.microsoft.com"
      };

      // Used to time download operations.
      Stopwatch stopwatch = new Stopwatch();

      // Compute the time required to download the URLs.
      stopwatch.Start();
      var downloads = from url in urls
                      select DownloadStringAsync(url);
      Task.WhenAll(downloads).ContinueWith(results =>
      {
         stopwatch.Stop();

         // Print the number of characters download and the elapsed time.
         Console.WriteLine("Retrieved {0} characters. Elapsed time was {1} ms.",
            results.Result.Sum(result => result.Length),
            stopwatch.ElapsedMilliseconds);
      })
      .Wait();

      // Perform the same operation a second time. The time required
      // should be shorter because the results are held in the cache.
      stopwatch.Restart();
      downloads = from url in urls
                  select DownloadStringAsync(url);
      Task.WhenAll(downloads).ContinueWith(results =>
      {
         stopwatch.Stop();

         // Print the number of characters download and the elapsed time.
         Console.WriteLine("Retrieved {0} characters. Elapsed time was {1} ms.",
            results.Result.Sum(result => result.Length),
            stopwatch.ElapsedMilliseconds);
      })
      .Wait();
   }
}

/* Sample output:
Retrieved 27798 characters. Elapsed time was 1045 ms.
Retrieved 27798 characters. Elapsed time was 0 ms.
*/
Imports System
Imports System.Collections.Concurrent
Imports System.Diagnostics
Imports System.Linq
Imports System.Net
Imports System.Threading.Tasks

' Demonstrates how to use Task<TResult>.FromResult to create a task 
' that holds a pre-computed result.
Friend Class CachedDownloads
   ' Holds the results of download operations.
   Private Shared cachedDownloads As New ConcurrentDictionary(Of String, String)()

   ' Asynchronously downloads the requested resource as a string.
   Public Shared Function DownloadStringAsync(ByVal address As String) As Task(Of String)
      ' First try to retrieve the content from cache.
      Dim content As String
      If cachedDownloads.TryGetValue(address, content) Then
         Return Task.FromResult(Of String)(content)
      End If

      ' If the result was not in the cache, download the 
      ' string and add it to the cache.
      Return Task.Run(async Function()
          content = await New WebClient().DownloadStringTaskAsync(address)
          cachedDownloads.TryAdd(address, content)
          Return content
      End Function)
   End Function

   Shared Sub Main(ByVal args() As String)
      ' The URLs to download.
      Dim urls() As String = { "http://msdn.microsoft.com", "http://www.contoso.com", "http://www.microsoft.com" }

      ' Used to time download operations.
      Dim stopwatch As New Stopwatch()

      ' Compute the time required to download the URLs.
      stopwatch.Start()
      Dim downloads = From url In urls _
                      Select DownloadStringAsync(url)
      Task.WhenAll(downloads).ContinueWith(Sub(results)
         ' Print the number of characters download and the elapsed time.
          stopwatch.Stop()
          Console.WriteLine("Retrieved {0} characters. Elapsed time was {1} ms.", results.Result.Sum(Function(result) result.Length), stopwatch.ElapsedMilliseconds)
      End Sub).Wait()

      ' Perform the same operation a second time. The time required
      ' should be shorter because the results are held in the cache.
      stopwatch.Restart()
      downloads = From url In urls _
                  Select DownloadStringAsync(url)
      Task.WhenAll(downloads).ContinueWith(Sub(results)
         ' Print the number of characters download and the elapsed time.
          stopwatch.Stop()
          Console.WriteLine("Retrieved {0} characters. Elapsed time was {1} ms.", results.Result.Sum(Function(result) result.Length), stopwatch.ElapsedMilliseconds)
      End Sub).Wait()
   End Sub
End Class

' Sample output:
'Retrieved 27798 characters. Elapsed time was 1045 ms.
'Retrieved 27798 characters. Elapsed time was 0 ms.
'

Este ejemplo calcula el tiempo necesario para descargar varias cadenas dos veces.This example computes the time that is required to download multiple strings two times. El segundo conjunto de operaciones de descarga tardará menos tiempo que el primer conjunto porque los resultados se mantienen en la memoria caché.The second set of download operations should take less time than the first set because the results are held in the cache. El FromResult método habilita el DownloadStringAsync método para crear Task<TResult> objetos que contienen estos precalculadas resultados.The FromResult method enables the DownloadStringAsync method to create Task<TResult> objects that hold these pre-computed results.

Compilar el códigoCompiling the Code

Copie el código de ejemplo y péguelo en un proyecto de Visual Studio o en un archivo denominado CachedDownloads.cs (CachedDownloads.vb para Visual BasicVisual Basic) y, a continuación, ejecute el siguiente comando en una ventana del símbolo del sistema de Visual Studio.Copy the example code and paste it in a Visual Studio project, or paste it in a file that is named CachedDownloads.cs (CachedDownloads.vb for Visual BasicVisual Basic), and then run the following command in a Visual Studio Command Prompt window.

Visual C#Visual C#

csc.exe CachedDownloads.cscsc.exe CachedDownloads.cs

Visual BasicVisual Basic

vbc.exe CachedDownloads.vbvbc.exe CachedDownloads.vb

Programación sólidaRobust Programming

Vea tambiénSee Also

Programación asincrónica basada en tareasTask-based Asynchronous Programming