How to: Create Pre-Computed Tasks

.NET Framework 4.5

This document describes how to use the Task.FromResult<TResult> method to retrieve the results of asynchronous download operations that are held in a cache. The FromResult<TResult> method returns a finished Task<TResult> object that holds the provided value as its Result property. 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.

The following example downloads strings from the web. It defines the DownloadStringAsync method. This method downloads strings from the web asynchronously. This example also uses a ConcurrentDictionary<TKey, TValue> object to cache the results of previous operations. If the input address is held in this cache, DownloadStringAsync uses the FromResult<TResult> method to produce a Task<TResult> object that holds the content at that address. 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.
*/

This example computes the time that is required to download multiple strings two times. The second set of download operations should take less time than the first set because the results are held in the cache. The FromResult<TResult> method enables the DownloadStringAsync method to create Task<TResult> objects that hold these pre-computed results.

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 Basic), and then run the following command in a Visual Studio Command Prompt window.

Visual C#

csc.exe CachedDownloads.cs

Visual Basic

vbc.exe CachedDownloads.vb

Was this page helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft