Question

Trying to run C# code example "How to: Create Pre-Computed Tasks" (MSDN) in .NET 4.0 Async CTP, having made changes:

  • Task.FromResult ---> TaskEx.FromResult
  • Task.FromResult ---> TaskEx.FromResult
  • Task.Run(async () => ---> TaskEx.RunEx(async () =>
    (also tried TaskEx.Run(async () =>)

butt getting the compilation error:

Since 'System.Func<System.Threading.Tasks.Task>' is async and returns Task, a return keyword must not be followed by an object expression

How to change the code in order to run this example?

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 TaskEx //****** Task.FromResult ---> TaskEx.FromResult   
             .FromResult<string>(content);
    }

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

  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);
    TaskEx.WhenAll(downloads)//*** Task.WhenAll -->  TaskEx.WhenAll
          .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);

    TaskEx.WhenAll(downloads)//*** Task.WhenAll -->  TaskEx.WhenAll
          .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();
  }
}

Update:

Does this code example without my updates for Async CTP run in .NET 4.5?

Was it helpful?

Solution

The C# compiler was enhanced in VS2012 to be smarter about generic overload resolution in the presence of async lambdas (i.e., Func<Task> and family). Since you're on VS2010, you'll have to help it out here and there.

The clue is in the type of your async lambda as displayed in your error message: System.Func<System.Threading.Tasks.Task>.

What it should be is System.Func<System.Threading.Tasks.Task<System.String>>.

So I would try this:

return TaskEx.RunEx<string> //****** Task.Run  --> TaskEx.RunEx (TaskEx.Run)
  (async () =>    
{
  content = await new WebClient().DownloadStringTaskAsync(address);
  cachedDownloads.TryAdd(address, content);
  return content;//*****Error
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top