0

I have my Program.cs file:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace AsyncTest
{
    class Program
    {

        static async Task Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            var interesting = new InterestingObject();

            List<int> list;
            List<int> alsoList;

            list = await interesting.GenerateListAsync();
            alsoList = interesting.GenerateList();

            Console.WriteLine("Done! :)");

            list    .ForEach(xs => Console.WriteLine(xs));
            alsoList.ForEach(xs => Console.WriteLine (xs));

        }

    }
}

And here's the code for InterestingObject:

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace AsyncTest
{
    public class InterestingObject
    {
        public InterestingObject()
        {
        }

        public List<int> GenerateList()
        {

            Console.WriteLine("Gonna generate the list!");

            var list = new List<int>();
            int i = 0;
            while (i < 5)
            {

                Random random = new Random();
                list.Add(random.Next());
                Console.WriteLine("Generated a new int!");
                VeryHeavyCalculations();

                i++;
            }

            return list;

        }

        public async Task<List<int>> GenerateListAsync()
        {

            Console.WriteLine("Gonna generate the list async!");

            var list = new List<int>();
            int i = 0;
            while (i < 5)
            {

                Random random = new Random();
                list.Add(random.Next ());
                Console.WriteLine("Generated a new int asyncronously!");
                await Task.Run(() => VeryHeavyCalculations());

                i++;
            }

            return list;

        }

        public void VeryHeavyCalculations()
        {
            Thread.Sleep (1000);
        }
    }
}

I expect list = await interesting.GenerateListAsync(); to run asynchronously while alsoList = interesting.GenerateList(); is running, effectively logging the output of GenerateList into my console while GenerateListAsync is doing the exact same, or to see GenerateListAsync finish near-instantly when GenerateList finishes.

However, looking into the console I see my application running GenerateListAsync and then run GenerateList afterwards.

I'm doing this wrong but no source has been sufficient to solve this problem.

4
  • 2
    It is running asynchronously, but the code does not continue until after await. If you want to kick that operation off and then move on then do not await the Task until some point later in your code. Commented Apr 1, 2019 at 16:41
  • 1
    This is ancillary to your question. You're doing new Random() in a loop. That's not going to end well for you. You're just going to create it with the same seed, and it's going to generate the same numbers. Commented Apr 1, 2019 at 16:41
  • @Crowcoder are you saying the compiler uses a lookahead to see if there are await's ahead, and it will run those asynchronously while it runs all the code preceding it? Commented Apr 1, 2019 at 16:43
  • No. You might consider downloading LINQPad and going through this samples library tutorial: Asynchrony in C# 5 Interactive Tutorial, updated for Framework 4.5 RTM Commented Apr 1, 2019 at 16:47

2 Answers 2

3

I expect list = await interesting.GenerateListAsync(); to run asynchronously whilealsoList = interesting.GenerateList(); is running,

That expectation is incorrect; the entire point of await is that it does not continue past that point until the asynchronous operation is complete; it does this with a range of tricks including async state machines that allow an incomplete operation to be resumed when the results come back in. You can, however, just move the point at which you await, so that it doesn't cause this perceived blockage:

List<int> list;
List<int> alsoList;

var pending = interesting.GenerateListAsync(); // no await
alsoList = interesting.GenerateList();
list = await pending; // essentially "joins" at this point... kind of

Note that async and parallelism are different things; they can be used together, but that isn't what happens by default. Note also: not all code is designed to allow concurrent usage, so you shouldn't do this kind of thing without knowing whether it is OK to use concurrent calls on a particular API.

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

5 Comments

Ah, I think I just get it now.. await isn't used to instruct something to run asynchronously, it's used to await operations that run asyncronously?
@Vanitas exactly
So then what happens if you use async on an object's member declaration? Do you have a source that explains in depth what is exactly going on?
@Vanitas async literally does nothing except enable the await keyword; as for what happens when you await - that's a really complex story
Upvoted. Don't understand the downvote. The is a succinct and accurate explanation of how the async/await pattern works, which was the problem in the original post.
0

Further to the answer, have a look at await (C# Reference)

The await operator is applied to a task in an asynchronous method to insert a suspension point in the execution of the method until the awaited task completes. that's the reason in your application running GenerateListAsync and then run GenerateList afterwards. To run the GenerateListAsync asynchronously you need to take the GenerateListAsync return in Task variable and then call GenerateList and after that use await for GenerateListAsync method.

e.g

Task <List<int>> longRunningTask = interesting.GenerateListAsync();
        alsoList = interesting.GenerateList();
        list = await longRunningTask;

1 Comment

"To run the GenerateListAsync asynchronously..." - You are confusing asynchrony with parallelism. It executes asynchronously (assuming implemented as such) even with await.

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.