loneshark99
loneshark99

Reputation: 724

Adding List of tasks without executing

I have a method which returns a task, which I want to call multiple times and wait for any 1 of them to be successful. The issue I am facing is as soon as I add the task to the List, it executes and since I added delay to simulate the work, it just block there.

Is there a way to add the the tasks to the list without really executing it and let whenAny execute the tasks.

The below code is from Linqpad editor.

async void  Main()
{
    var t = new Test();
    List<Task<int>> tasks = new List<Task<int>>();

    for( int i =0; i <  5; i++)
    {
        tasks.Add(t.Getdata());
    }

    var result = await Task.WhenAny(tasks);

    result.Dump();
}

public class Test
{
   public Task<int> Getdata()
   {
      "In Getdata method".Dump();
      Task.Delay(90000).Wait();
      return Task.FromResult(10);
   }
}

Update :: Below one makes it clear, I was under the impression that if GetData makes a call to network it will get blocked during the time it actually completes.

async void Main()
{
 OverNetwork t = new OverNetwork();
 List<Task<string>> websitesContentTask = new List<Task<string>>();
 websitesContentTask.Add(t.GetData("http://www.linqpad.net"));
 websitesContentTask.Add(t.GetData("http://csharpindepth.com"));
 websitesContentTask.Add(t.GetData("http://www.albahari.com/nutshell/"));
 Task<string> completedTask = await Task.WhenAny(websitesContentTask);
 string output = await completedTask;
 Console.WriteLine(output);
}

public class OverNetwork
{
    private HttpClient client = new HttpClient();

    public Task<string> GetData(string uri)
    {
        return client.GetStringAsync(uri);
    } 
}

Upvotes: 1

Views: 3987

Answers (2)

Stephen Cleary
Stephen Cleary

Reputation: 456617

since I added delay to simulate the work, it just block there

Actually, your problem is that your code is calling Wait, which blocks the current thread until the delay is completed.

To properly use Task.Delay, you should use await:

public async Task<int> Getdata()
{
  "In Getdata method".Dump();
  await Task.Delay(90000);
  return 10;
}

Is there a way to add the the tasks to the list without really executing it and let whenAny execute the tasks.

No. WhenAny never executes tasks. Ever.

It's possible to build a list of asynchronous delegates, i.e., a List<Func<Task>> and execute them later, but I don't think that's what you're really looking for.

Upvotes: 4

Jan Zahradn&#237;k
Jan Zahradn&#237;k

Reputation: 2497

There are multiple tasks in your Getdata method. First does delay, but you are returning finished task which returned 10. Try to change your code like this

return Task.Delay(90000).ContinueWith(t => 10)

Upvotes: 1

Related Questions