user2224583
user2224583

Reputation: 79

C# multiple async tasks and where to properly await them when they use each other to complete?

I have two methods that are similar, however, after theorizing about this, I'm pretty sure they are different in execution.

MethodOne:

        var renderDocumentDirective = await 
        RenderDocumentBuilder.Instance.GetRenderDocumentDirectiveAsync(previousPage, session);

        return await ResponseClient.Instance.BuildAlexaResponse(new Response()
        {
            shouldEndSession = null,
            directives = new List<IDirective>()
            {
                renderDocumentDirective
            }

        }, session.alexaSessionDisplayType);

MethodTwo

            var renderDocumentDirective = RenderDocumentBuilder.Instance.GetRenderDocumentDirectiveAsync(previousPage, session);
            return await ResponseClient.Instance.BuildAlexaResponse(new Response()
            {
                shouldEndSession = null,
                directives = new List<IDirective>()
                {
                    await renderDocumentDirective
                }

            }, session.alexaSessionDisplayType);

The first method uses the await operator on the async task, RenderDocumentBuilder, prior to its uses inside the ResponseClient, which is also an async task.

However the second method, sets up the Task RenderDocumentBuilder, but doesn't call the awaited method until it is inside the ResponseClient, which, at this point in execution, is waiting to return data.

Both ways of executing this method work, but I am unclear if it is proper to:

Upvotes: 0

Views: 573

Answers (1)

Ackdari
Ackdari

Reputation: 3498

I think you misinterpret the flow of data.

Here are your two methods written a bit more verbose

Method 1

var renderTask = RenderDocumentBuilder.Instance.GetRenderDocumentDirectiveAsync(previousPage, session);

var renderDocumentDirective = await renderTask;

var alexaResponse = new Response();

alexaResponse.shouldEndSession = null,
alexaResponse.directives = new List<IDirective>();
alexaResponse.directives.Add(renderDocumentDirective);

var buildTask = ResponseClient.Instance.BuildAlexaResponse(alexaResponse, session.alexaSessionDisplayType);

return await buildTask;

Method 2

var renderTask = RenderDocumentBuilder.Instance.GetRenderDocumentDirectiveAsync(previousPage, session);

var alexaResponse = new Response()
alexaResponse.shouldEndSession = null,
alexaResponse.directives = new List<IDirective>();
alexaResponse.directives.Add(await renderTask);

var buildTask = ResponseClient.Instance.BuildAlexaResponse(alexaResponse, session.alexaSessionDisplayType);

return await buildTask;

So you see that the only real difference is that methode 2 creates the Response object, sets shouldEndSession and creates the List object before or it awaits the renderTask.

Method 2 might be beneficial, but this depends on how GetRenderDocumentDirectiveAsync is implemented (i.e. truely async). But even if it is, it is highly unlikly that method 2 brings any performance gains as there is not much difference between both methods.

That said, I would go with method 1, because it looks more like sync code and in most cases you want to await a Task as soon you have it available, because await/async is mainly about freeing threads to do other stuff and not about parallalism.

Upvotes: 2

Related Questions