0

I wanted to call / run three tasks parallely and then wait for their results. From my service class what I did is ...

        var _validChapterCodesTask = gd.validateChapterCodeDetails(_input1);

        var _validGroupCodesTask = gd.validateGroupCodeDetails(_input1); 

        await Task.WhenAll(_validChapterCodesTask, _validGroupCodesTask);

        var _validChapterCodes = await _validChapterCodesTask;

        var _validGroupCodes = await _validGroupCodesTask;

And in my DAL Class , the definitions look like :

   public async Task<IEnumerable<ChapterCodeValidationOutput>> validateChapterCodeDetails(GroupMembershipValidationInput gmvi)
    {
        Repository rep = new Repository();
        if (!gmvi._chapterCodes.All(x => x.Equals("")))
        {
            var _validChapterCodes = await rep.ExecuteSqlQueryAsync(typeof(ChapterCodeValidationOutput),SQL.Upload.UploadValidation.getChapterCodeValidationSQL(gmvi._chapterCodes), null);
            return (IEnumerable<ChapterCodeValidationOutput>)_validChapterCodes;
        }
        else
            return new List<ChapterCodeValidationOutput>();
    }


    public async Task<IEnumerable<GroupCodeValidationOutput>> validateGroupCodeDetails(GroupMembershipValidationInput gmvi)
    {
        Repository rep = new Repository();
        if (!gmvi._chapterCodes.All(x => x.Equals("")))
        {
            var _validGroupCodes = await rep.ExecuteSqlQueryAsync(typeof(GroupCodeValidationOutput), SQL.Upload.UploadValidation.getGroupCodeValidationSQL(gmvi._groupCodes), null);
            return (IEnumerable<GroupCodeValidationOutput>)_validGroupCodes;
        }
        else
            return new List<GroupCodeValidationOutput>();
    }

But these are not working as expected ? The breakpoints hit show that one by one the method is getting called from service, going to DAL, execute the DB Query and comeback and assign to respective variables.

And as soon as it hits

await Task.WhenAll(_validChapterCodesTask, _validGroupCodesTask);

The next few lines are not hit and the control returns to the invoking controller.

How would I get back their results and fire them parallely and wait for their results only?

What am I doing wrong ?

StrugglingCoder
  • 4,781
  • 16
  • 69
  • 103
  • 1
    Try: var _validChapterCodes = _validChapterCodesTask.Result; var _validGroupCodes = _validGroupCodesTask.Result; – Leonid Malyshev Jun 24 '16 at 11:50
  • Possible duplicate of [Awaiting multiple Tasks with different results](http://stackoverflow.com/questions/17197699/awaiting-multiple-tasks-with-different-results) – Nkosi Jun 24 '16 at 12:02
  • `The breakpoints hit show that one by one the method... comeback and assign to respective variables.` Are you *stepping through them*? – Stephen Cleary Jun 24 '16 at 12:21
  • Where is the first code located in your program? Could there be a line where you don't `await` a call stack? Or having `async void` method? – shay__ Jun 24 '16 at 13:09
  • I am confused by the question; an await *is* a return to the caller; that's the whole point of *await* is that *your caller gets to do work while the task executes asynchronously*. Why is it surprising that the await returns? – Eric Lippert Jun 24 '16 at 13:23
  • I thought I at least would wait for the results . And then when the results would come back from DAL in service , then I would return from service class ... to the invoking controller. How would I achieve that ? This is what I tried to implement http://stackoverflow.com/questions/17197699/awaiting-multiple-tasks-with-different-results – StrugglingCoder Jun 24 '16 at 13:42
  • @EricLippert .. Please suggest a way how can I achieve that ? I may be in the wrong direction. – StrugglingCoder Jun 24 '16 at 13:43
  • 1
    An asynchronous wait is just that: **asynchronous**. It does not mean "synchronously wait for the result and then return it". It means "return immediately so that the caller can do more work, and resume at this point after the results are available". If those are not the semantics you intend then why are you writing *any* asynchronous code? – Eric Lippert Jun 24 '16 at 13:48
  • @EricLippert .. as per the answer in the question given by Stephen Cleary ... I would fire those methods parallely and then only at their results and eventually after they come back , I would return to my invoking controller . That is what I want to do . But why is every method getting called on by one like validateChapterCodeDetails gets called and then from DB the results would return and then the next would be called ? Please tell how can I achieve that ? – StrugglingCoder Jun 24 '16 at 13:59
  • I understand what you want to do; what I don't understand is what is the *point* of doing that? You would take on *all the costs* of asynchrony in exchange for *none of the benefits*. You gain the benefits by *plumbing the asynchrony into the caller*. Your asynchronous method returns a task; the question should be "what is the *continuation* of this task?" That is, what must follow *after* the task is done? Put that code after an `await` of the task, in the caller. – Eric Lippert Jun 24 '16 at 15:53

1 Answers1

0

await Task.WhenAll(_validChapterCodesTask, _validGroupCodesTask)

creates a Task that should be waited for. Use await in the invoking controller.

Andriy Tolstoy
  • 5,690
  • 2
  • 31
  • 30