简体   繁体   中英

Running parallel async tasks?

So I've been searching StackOverflow/Google for different methods of running multiple async tasks concurrently. There seemed to be quite the debate between different methods and I just wanted to get some clarification. I'm writing a program to execute a JSON POST request until the server returns a status code of 200. Let's say I want to run 5 of theses tasks in parallel until one returns a status code of 200. Please try not to stray away from the topic, I have no control over the server! Here's my current code,

    static bool status = false;
    public static async Task getSessionAsync() {
        while(!status) { ... } 
    }
    public static async Task doMoreStuff() {
       ...
    }
    public static async Task RunAsync() 
    {
        await getSessionAsync ();
        await doMoreStuff();
    }
    public static void Main (string[] args)
    {
        Task.WhenAll(RunAsync()).GetAwaiter().GetResult();
    }

Basically, I'm wondering if it's wrong for me to approach it like this,

    public static async Task RunAsync() 
    {
        for(int i = 0; i < 5; i++) {
            await getSessionAsync ();
        }
        await doMoreStuff();
    }

Assuming:

private Task<MySession> GetSessionAsync()
{
    // ...
}

Option 1

Task.WhenAny

var session = await await Task.WhenAny(Enumerable.Range(0, 5).Select(_ => GetSessionAsync()));

Option 2

You could use the Rx LINQ method called Amb which will observe only the first Observable that returns something.

var session = await Enumerable.Range(0, 5).Select(_ => GetSessionAsync().ToObservable()).Amb().ToTask();

This will not run in parallel:

public static async Task RunAsync() 
{
    for(int i = 0; i < 5; i++) {
        await getSessionAsync ();
    }
    await doMoreStuff();
}

You have to use Task.WhenAny()

public static async Task RunAsync() 
{
    var tasks = new List<Task>();
    for(int i = 0; i < 5; i++) {
        tasks.Add(getSessionAsync());
    }
    await Task.WhenAny(tasks);
    await doMoreStuff();
}

If you do not need your current context (ie when you are writing a Library and not Frontend code), don't forget to use ConfigureAwait(false) after each await.

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