Base solution for your next web application
Starts in:
01 DAYS
01 HRS
01 MIN
01 SEC
Open Closed

Parallel asynchronous calls in AppService #902


User avatar
0
doubledp created

Hi,

Could you please help me with the following:

I am trying to execute async calls is parallel and only use execute subsequent code after all the async tasks have been completed.

Here is the code:

public async Task<LabourSalesHighlightsDto> GetLabourSalesHighlights(LabourSalesAggregateInput input)
        {
            LabourSalesHighlightsDto labourSalesHighlights = new LabourSalesHighlightsDto();

            var labourSalesOperatorAggregateTask = GetLabourSalesAggregation_ByCompanyNumber_ByOperatorName(input);
            var labourSalesInvoicingAggregateTask = GetLabourSalesAggregation_ByCompanyNumber_ByInvoicing(input);
            var labourSalesCreditingAggregateTask = GetLabourSalesAggregation_ByCompanyNumber_ByCredits(input);

            await Task.WhenAll(labourSalesOperatorAggregateTask, labourSalesInvoicingAggregateTask, labourSalesCreditingAggregateTask);

            var labourSalesOperatorAggregate = labourSalesOperatorAggregateTask.Result;
            var labourSalesInvoicingAggregate = labourSalesInvoicingAggregateTask.Result;
            var labourSalesCreditingAggregate = labourSalesCreditingAggregateTask.Result;

            labourSalesHighlights.SalesTopTotal = labourSalesOperatorAggregate.Items.Select(lsa => lsa.Value).FirstOrDefault();
            labourSalesHighlights.SalesTopName = labourSalesOperatorAggregate.Items.Select(lsa => lsa.Label).FirstOrDefault();
            labourSalesHighlights.SalesTopDescription = labourSalesOperatorAggregate.Items.Select(lsa => lsa.CompanyName).FirstOrDefault();

            labourSalesHighlights.InvoicingTotal = labourSalesInvoicingAggregate.Items.Select(lsa => lsa.Value).Sum();
            labourSalesHighlights.InvoicingBestName = labourSalesInvoicingAggregate.Items.Select(lsa => lsa.Label).FirstOrDefault();
            labourSalesHighlights.InvoicingWorstName = labourSalesInvoicingAggregate.Items.Select(lsa => lsa.Label).LastOrDefault();

            labourSalesHighlights.CreditingTotal = labourSalesCreditingAggregate.Items.Select(lsa => lsa.Value).Sum();
            labourSalesHighlights.CreditingBestName = labourSalesCreditingAggregate.Items.Select(lsa => lsa.Label).FirstOrDefault();
            labourSalesHighlights.CreditingWorstName = labourSalesCreditingAggregate.Items.Select(lsa => lsa.Label).LastOrDefault();

            return labourSalesHighlights;
        }

When I don't inherit from AppServiceBase for this particular service, the code is working with the only exception that the audit log entry does not get created then.

When I inherit from AppServiceBase for this particular service, the execution of the above method results in an exception as per below:

System.NotSupportedException: A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.

I want to inherit from AppServiceBase so that my method call gets logged to the Audit Log table.

Please help!


3 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Same situation is answered here. #668@37243a73-e69b-4f6c-b607-73f85972ce49

    I hope this helps.

  • User Avatar
    0
    doubledp created

    Hi,

    Thank you for this. I have seen that post.

    Not quite sure what Halil means by if you are not in a UOW there would be no problem. Another thing that I don't get is when I remove the inheritance of AppServiceBase my code works correctly.

    I am hoping Halil can point me in the right direction.

  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    You can inherit from your AppServiceBase and disable UOW for your method:

    [UnitOfWork(IsDisabled = true)]
    public async Task<LabourSalesHighlightsDto> GetLabourSalesHighlights(LabourSalesAggregateInput input)
    {
        //...
    }
    

    To understand it better, you can see documents: <a class="postlink" href="http://www.aspnetboilerplate.com/Pages/Documents/Unit-Of-Work#DocDisablingUow">http://www.aspnetboilerplate.com/Pages/ ... sablingUow</a>

    Have a nice day.