简体   繁体   中英

How working with async/await

I have the following scenario:

I'm processing three "heavy working" methods, in combination with async I would do this parallel. But it doesn't work, can anyone tell me, what I haven't understood?

Here's my code:

static void Main(string[] args)
    {
        var watch = new Stopwatch();
        watch.Start();

        var result = GetStringAsync();

        var time = watch.ElapsedMilliseconds;
    }

    static async Task<string> GetStringAsync()
    {
        var result = "";
        result += await H1();
        result += await H2();
        result += await H3();

        return result;

    }

    static async Task<string> H1()
    {
        Console.WriteLine("entered h1");
        Thread.Sleep(10000);
        return "1";
    }

    static async Task<string> H2()
    {
        Console.WriteLine("entered h2");
        Thread.Sleep(10000);
        return "2";
    }

    static async Task<string> H3()
    {
        Console.WriteLine("entered h3");
        Thread.Sleep(10000);
        return "3";
    }

Instead of blocking the threads with Thread.Sleep() which is synchronously blocking, use await Task.Delay() - which is asynchronous.

Also, await will still wait for each method to complete. Get all the tasks back from each method and then wait for them all to complete:

static void Main(string[] args)
{
    var watch = new Stopwatch();
    watch.Start();

    var result = GetStringAsync(); 
    result.Wait();        

    var time = watch.ElapsedMilliseconds;

    Console.WriteLine(result.Result + ":" +  time);
}

static async Task<string> GetStringAsync()
{
    var result1 = H1();
    var result2 = H2();
    var result3 = H3();

    await Task.WhenAll(result1,result2,result3);

    return result1.Result + result2.Result + result3.Result;            
}

static async Task<string> H1()
{
    Console.WriteLine("entered h1");
    await Task.Delay(TimeSpan.FromSeconds(10));
    return "1";
}

static async Task<string> H2()
{
    Console.WriteLine("entered h2");
    await Task.Delay(TimeSpan.FromSeconds(10));
    return "2";
}

static async Task<string> H3()
{
    Console.WriteLine("entered h3");
    await Task.Delay(TimeSpan.FromSeconds(10));
    return "3";
}

I would like to refer you to this stackoverflow post :

    async Task LongTask1() { ... }
    async Task LongTask2() { ... }
    ...
    {
       // Start the stopwatch

       var watch = new Stopwatch();
       watch.Start();

       // Do Async Tasks

       Task t1 = LongTask1();
       Task t2 = LongTask2();
       await Task.WhenAll(t1,t2); //now we have t1.Result and t2.Result          

       // Now we have the time it took to complete all the async tasks

       var time = watch.ElapsedMilliseconds;
    }

For a complete understanding of async/await, please refer to this tutorial on MSDN .

In this Code:

Task<string> getStringResult = GetStringAsync();

Thread.Sleep(5000) // some long run working

string result = await getStringResult;

basically you get a result in a context seperated from where it ran before and asynchronously.

In previous model we have to write it like this:

class StringMaker
{
    GetStringAsync();
    event EventHandler<string> StringReceived;
}

and then use it like:

StringMaker sm = new StringMaker();
sm.StringReceived += sm_StringReceived;
sm.GetStringAsync();

and handler that is not in our desired context:

void sm_StringReceived(string e)
{
    string result = e;
}

Okay, I think I've understood it. Can someone check this:

static void Main(string[] args)
{
    var task = GetNameAsync();
    task.Wait();

    var result = task.Result;
    Console.WriteLine(result);
}

static async Task<string> GetNameAsync()
{
    var first = FetchFirstNameAsync();
    var second = FetchLastNameAsync();

    Console.WriteLine("I'm first...");

    await Task.WhenAll(first, second);

    return first.Result + " " + second.Result;
}

private static async Task<string> FetchFirstNameAsync()
{
    Console.WriteLine("entered1");
    return await Task.Factory.StartNew(() =>
    {
        var counter = 0;

        for (var index = 0; index < 20000; index++)
        {
            Task.Delay(1);
            counter++;
            Console.WriteLine("handled1");
        }

        return counter.ToString(CultureInfo.InvariantCulture) + "First";
    });
}

private static async Task<string> FetchLastNameAsync()
{
    Console.WriteLine("entered1");
    return await Task.Factory.StartNew(() =>
    {
        var counter = 0;

        for (var index = 0; index < 20000; index++)
        {
            Task.Delay(1);
            counter++;
            Console.WriteLine("handled2");
        }

        return counter.ToString(CultureInfo.InvariantCulture) + "Last";
    });
}

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