简体   繁体   中英

Creating a lambda expression for a task<string>

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;
        }
    }
}

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.

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";
}))();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM