ConfigureAwait(false) - Does the continuation always run on different thread?












2















This question is asked in the context of ASP.NET WebApi 2 (not ASP.NET Core). I have tried to do my own research on this topic, however I could not find the explicit answer to this.



The official MSDN documentation for the ConfigureAwait(...) method parameter states following:




true to attempt to marshal the continuation back to the original context captured; otherwise, false.




Stephen Toub further explains the attempt keyword as follows:




That means there may not be anything to marshal back to... there may not be a context to capture, e.g. SynchronizationContext.Current may return null.




If I understand it correctly, then this is not the case for the ASP.NET WebApi 2, because there is AspNetSynchronizationContext present, right?



Now lets take a look at following controller action method:



[HttpGet]
public async Task<String> GetValues()
{
// First half.

var values = await HeavyIo().ConfigureAwait(false);

// Second half.

return values;
}


By passing continueOnCapturedContext: false is it guaranteed that that the continuation labeled as // Second half. gets always executed on different thread? Or is there chance that if the thread on which the synchronization context got captured will be free when async operation completes, then the continuation will run on that same thread?










share|improve this question



























    2















    This question is asked in the context of ASP.NET WebApi 2 (not ASP.NET Core). I have tried to do my own research on this topic, however I could not find the explicit answer to this.



    The official MSDN documentation for the ConfigureAwait(...) method parameter states following:




    true to attempt to marshal the continuation back to the original context captured; otherwise, false.




    Stephen Toub further explains the attempt keyword as follows:




    That means there may not be anything to marshal back to... there may not be a context to capture, e.g. SynchronizationContext.Current may return null.




    If I understand it correctly, then this is not the case for the ASP.NET WebApi 2, because there is AspNetSynchronizationContext present, right?



    Now lets take a look at following controller action method:



    [HttpGet]
    public async Task<String> GetValues()
    {
    // First half.

    var values = await HeavyIo().ConfigureAwait(false);

    // Second half.

    return values;
    }


    By passing continueOnCapturedContext: false is it guaranteed that that the continuation labeled as // Second half. gets always executed on different thread? Or is there chance that if the thread on which the synchronization context got captured will be free when async operation completes, then the continuation will run on that same thread?










    share|improve this question

























      2












      2








      2


      1






      This question is asked in the context of ASP.NET WebApi 2 (not ASP.NET Core). I have tried to do my own research on this topic, however I could not find the explicit answer to this.



      The official MSDN documentation for the ConfigureAwait(...) method parameter states following:




      true to attempt to marshal the continuation back to the original context captured; otherwise, false.




      Stephen Toub further explains the attempt keyword as follows:




      That means there may not be anything to marshal back to... there may not be a context to capture, e.g. SynchronizationContext.Current may return null.




      If I understand it correctly, then this is not the case for the ASP.NET WebApi 2, because there is AspNetSynchronizationContext present, right?



      Now lets take a look at following controller action method:



      [HttpGet]
      public async Task<String> GetValues()
      {
      // First half.

      var values = await HeavyIo().ConfigureAwait(false);

      // Second half.

      return values;
      }


      By passing continueOnCapturedContext: false is it guaranteed that that the continuation labeled as // Second half. gets always executed on different thread? Or is there chance that if the thread on which the synchronization context got captured will be free when async operation completes, then the continuation will run on that same thread?










      share|improve this question














      This question is asked in the context of ASP.NET WebApi 2 (not ASP.NET Core). I have tried to do my own research on this topic, however I could not find the explicit answer to this.



      The official MSDN documentation for the ConfigureAwait(...) method parameter states following:




      true to attempt to marshal the continuation back to the original context captured; otherwise, false.




      Stephen Toub further explains the attempt keyword as follows:




      That means there may not be anything to marshal back to... there may not be a context to capture, e.g. SynchronizationContext.Current may return null.




      If I understand it correctly, then this is not the case for the ASP.NET WebApi 2, because there is AspNetSynchronizationContext present, right?



      Now lets take a look at following controller action method:



      [HttpGet]
      public async Task<String> GetValues()
      {
      // First half.

      var values = await HeavyIo().ConfigureAwait(false);

      // Second half.

      return values;
      }


      By passing continueOnCapturedContext: false is it guaranteed that that the continuation labeled as // Second half. gets always executed on different thread? Or is there chance that if the thread on which the synchronization context got captured will be free when async operation completes, then the continuation will run on that same thread?







      c# asp.net .net asp.net-web-api async-await






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 24 '18 at 9:14









      MarkkknkMarkkknk

      16918




      16918
























          1 Answer
          1






          active

          oldest

          votes


















          4














          When asked in the negative form like that the answer is, i think, pretty clear - there is no guarantee that the second half will be executed on a different thread to the first half. As you speculate, the original thread might well be the lucky next-to-be-picked available thread, when the continuation is up for executing.



          Also important to note is that it's the context, not necessarily the thread, that is restored. In the case of a Windows message loop (e.g. WinForms UI thread), it is the UI thread running the message loop that picks up and executes the continuation, hence with ConfigureAwait(true), the same thread is guaranteed. With other SynchronizationContexts, though, there might be no particular reason to require or even prefer the original thread, as long as whatever is considered by them to be "context" is restored; e.g. HttpContext.Current [, identity, culture] in ASP.NET.



          There is also an at-least theoretical chance that HeavyIo() completes synchronously, in which case there is no context-switching anyway, and the second half will simply continue on the same thread as the first. I can only assume from your choice of naming ("heavy") that you're implying this won't be an option.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53456754%2fconfigureawaitfalse-does-the-continuation-always-run-on-different-thread%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            4














            When asked in the negative form like that the answer is, i think, pretty clear - there is no guarantee that the second half will be executed on a different thread to the first half. As you speculate, the original thread might well be the lucky next-to-be-picked available thread, when the continuation is up for executing.



            Also important to note is that it's the context, not necessarily the thread, that is restored. In the case of a Windows message loop (e.g. WinForms UI thread), it is the UI thread running the message loop that picks up and executes the continuation, hence with ConfigureAwait(true), the same thread is guaranteed. With other SynchronizationContexts, though, there might be no particular reason to require or even prefer the original thread, as long as whatever is considered by them to be "context" is restored; e.g. HttpContext.Current [, identity, culture] in ASP.NET.



            There is also an at-least theoretical chance that HeavyIo() completes synchronously, in which case there is no context-switching anyway, and the second half will simply continue on the same thread as the first. I can only assume from your choice of naming ("heavy") that you're implying this won't be an option.






            share|improve this answer




























              4














              When asked in the negative form like that the answer is, i think, pretty clear - there is no guarantee that the second half will be executed on a different thread to the first half. As you speculate, the original thread might well be the lucky next-to-be-picked available thread, when the continuation is up for executing.



              Also important to note is that it's the context, not necessarily the thread, that is restored. In the case of a Windows message loop (e.g. WinForms UI thread), it is the UI thread running the message loop that picks up and executes the continuation, hence with ConfigureAwait(true), the same thread is guaranteed. With other SynchronizationContexts, though, there might be no particular reason to require or even prefer the original thread, as long as whatever is considered by them to be "context" is restored; e.g. HttpContext.Current [, identity, culture] in ASP.NET.



              There is also an at-least theoretical chance that HeavyIo() completes synchronously, in which case there is no context-switching anyway, and the second half will simply continue on the same thread as the first. I can only assume from your choice of naming ("heavy") that you're implying this won't be an option.






              share|improve this answer


























                4












                4








                4







                When asked in the negative form like that the answer is, i think, pretty clear - there is no guarantee that the second half will be executed on a different thread to the first half. As you speculate, the original thread might well be the lucky next-to-be-picked available thread, when the continuation is up for executing.



                Also important to note is that it's the context, not necessarily the thread, that is restored. In the case of a Windows message loop (e.g. WinForms UI thread), it is the UI thread running the message loop that picks up and executes the continuation, hence with ConfigureAwait(true), the same thread is guaranteed. With other SynchronizationContexts, though, there might be no particular reason to require or even prefer the original thread, as long as whatever is considered by them to be "context" is restored; e.g. HttpContext.Current [, identity, culture] in ASP.NET.



                There is also an at-least theoretical chance that HeavyIo() completes synchronously, in which case there is no context-switching anyway, and the second half will simply continue on the same thread as the first. I can only assume from your choice of naming ("heavy") that you're implying this won't be an option.






                share|improve this answer













                When asked in the negative form like that the answer is, i think, pretty clear - there is no guarantee that the second half will be executed on a different thread to the first half. As you speculate, the original thread might well be the lucky next-to-be-picked available thread, when the continuation is up for executing.



                Also important to note is that it's the context, not necessarily the thread, that is restored. In the case of a Windows message loop (e.g. WinForms UI thread), it is the UI thread running the message loop that picks up and executes the continuation, hence with ConfigureAwait(true), the same thread is guaranteed. With other SynchronizationContexts, though, there might be no particular reason to require or even prefer the original thread, as long as whatever is considered by them to be "context" is restored; e.g. HttpContext.Current [, identity, culture] in ASP.NET.



                There is also an at-least theoretical chance that HeavyIo() completes synchronously, in which case there is no context-switching anyway, and the second half will simply continue on the same thread as the first. I can only assume from your choice of naming ("heavy") that you're implying this won't be an option.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 24 '18 at 10:09









                sellotapesellotape

                5,62821619




                5,62821619






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53456754%2fconfigureawaitfalse-does-the-continuation-always-run-on-different-thread%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Contact image not getting when fetch all contact list from iPhone by CNContact

                    count number of partitions of a set with n elements into k subsets

                    A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks