4

How would I create a lambda expression for a task that returns a string?

This is what I have tried but I get an error.

Thank you for any help.

public static async Task<string> GetStringAsync(string path)
    {
        try
        {
            var task = new Task<string>(async () =>
            {
                var response = await Client.GetAsync(path);

                var responsestring = await response.Content.ReadAsStringAsync();

                return responsestring;
            });

            return await Task.WhenAny(task, Task.Delay(20000)) == task
                ? task.Result
                : RequestTimeOutMessage;
        }
        catch (Exception e)
        {
            return e.GetBaseException().Message;
        }
    }
}
1
  • try and replace your task initialization with the following i.e. var task = Task.Run(()=> { var response = await Client.GetAsync(path); var responsestring = await response.Content.ReadAsStringAsync(); return responsestring; }); Commented Mar 18, 2018 at 0:19

2 Answers 2

11

You should never use the Task constructor. There are literally no good reasons to use it.

Your problem can be naturally expressed as a separate method:

public static async Task<string> GetStringAsync(string path)
{
  try
  {
    var task = DoGetStringAsync(path);

    return await Task.WhenAny(task, Task.Delay(20000)) == task
        ? await task
        : RequestTimeOutMessage;
  }
  catch (Exception e)
  {
    return e.GetBaseException().Message;
  }
}

private async Task<string> DoGetStringAsync(string path)
{
  var response = await Client.GetAsync(path);
  var responsestring = await response.Content.ReadAsStringAsync();
  return responsestring;
}

If you really want an async lambda expression (personally, I think it obfuscates the code unnecessarily), you can move the separate method inline and assign it to an asynchronous delegate type:

public static async Task<string> GetStringAsync(string path)
{
  try
  {
    Func<Task<string>> func = () =>
    {
      var response = await Client.GetAsync(path);
      var responsestring = await response.Content.ReadAsStringAsync();
      return responsestring;
    };
    var task = func();

    return await Task.WhenAny(task, Task.Delay(20000)) == task
        ? await task
        : RequestTimeOutMessage;
  }
  catch (Exception e)
  {
    return e.GetBaseException().Message;
  }
}

On a side note, I recommend using exceptions for timeouts as well as communication errors, rather than special strings.

Sign up to request clarification or add additional context in comments.

3 Comments

I'm probably missing something, but I'm coming from JavaScript, and it's so much easier to instantiate an array of promises using new Promise(...) for each promise in promises, then do a simple await Promise.all(promises)... Is there a simple solution like that here in C# (using Task instead of Promise)? This is for the common case (in my head), which I think corresponds to what you call dynamic task parallelization, as you called it in your linked article.
Using the lambda-expression method that you proposed above, as well as LINQ (kind of mentioned in your article, well, the PLINQ version), was able to do the following, which isn't too different from how I'd do it in JavaScript/TypeScript: var asyncWork = new List<Func<Task>>(); /* ... */ await Task.WhenAll(asyncWork.Select(f => f()));
@user3773048: A List<Task> may be a simpler solution. Task is pretty much Promise and Task.WhenAll is pretty much Promise.all. Some details differ (e.g. if one of them throws an exception).
7

This is the "simplest" way I'm aware of:

//Without result
var task = ((Func<Task>)(async () =>{
    await Task.Delay(100);    
}))();

//With result
var task2 = ((Func<Task<string>>)(async () =>{
    await Task.Delay(100);
    return "your-string";
}))();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.