简体   繁体   中英

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:

  • await a task outside the ResponseClient? (method 1)

  • Or, is it proper to create the renderDocumentDirective Task outside the ResponseClient and await it inside the method? (method 2)

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 (ie 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.

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