C# Async await deadlock problem gone in .NetCore?










6














In .NetFramework there was a high risk of a deadlock occuring when synchronizing to the synchronization context using:



var result = asyncMethod().Result; 
var result = asyncMethod().GetAwaiter().GetResult();


instead of



var result = await asyncMethod();


(read Stephen Cleary blogpost for more info)



Since the synchronization context has been removed in .NetCore. Does this mean that the above methods are now safe to use?










share|improve this question

















  • 2




    I'd go with "marginally less likely to explode and maim you"... they're still hugely problematic and best avoided, with a slight caveat around "unless you have checked, and already know that they completed successfully"
    – Marc Gravell
    Nov 12 at 15:37







  • 1




    @MarcGravell: But if you already know that they completed successfully then await does not yield, so in that case you might as well just use await.
    – Eric Lippert
    Nov 12 at 18:52






  • 3




    @EricLippert there are cases - especially in IO/perf code - where the state machine overhead is very measurable and a lot of the calls turn out to be sync; in those cases, there are demonstrable benefits in having a pure sync fast path with an async fallback; I acknowledge that this is probably a niche area - and certainly one that impacts library/framework authors a lot more than it impacts application authors: but it is a very real thing; as an aside: local functions work nicely for this case, it turns out - but usually in the proposed "static local function" sense (no capture state)
    – Marc Gravell
    Nov 12 at 19:21
















6














In .NetFramework there was a high risk of a deadlock occuring when synchronizing to the synchronization context using:



var result = asyncMethod().Result; 
var result = asyncMethod().GetAwaiter().GetResult();


instead of



var result = await asyncMethod();


(read Stephen Cleary blogpost for more info)



Since the synchronization context has been removed in .NetCore. Does this mean that the above methods are now safe to use?










share|improve this question

















  • 2




    I'd go with "marginally less likely to explode and maim you"... they're still hugely problematic and best avoided, with a slight caveat around "unless you have checked, and already know that they completed successfully"
    – Marc Gravell
    Nov 12 at 15:37







  • 1




    @MarcGravell: But if you already know that they completed successfully then await does not yield, so in that case you might as well just use await.
    – Eric Lippert
    Nov 12 at 18:52






  • 3




    @EricLippert there are cases - especially in IO/perf code - where the state machine overhead is very measurable and a lot of the calls turn out to be sync; in those cases, there are demonstrable benefits in having a pure sync fast path with an async fallback; I acknowledge that this is probably a niche area - and certainly one that impacts library/framework authors a lot more than it impacts application authors: but it is a very real thing; as an aside: local functions work nicely for this case, it turns out - but usually in the proposed "static local function" sense (no capture state)
    – Marc Gravell
    Nov 12 at 19:21














6












6








6







In .NetFramework there was a high risk of a deadlock occuring when synchronizing to the synchronization context using:



var result = asyncMethod().Result; 
var result = asyncMethod().GetAwaiter().GetResult();


instead of



var result = await asyncMethod();


(read Stephen Cleary blogpost for more info)



Since the synchronization context has been removed in .NetCore. Does this mean that the above methods are now safe to use?










share|improve this question













In .NetFramework there was a high risk of a deadlock occuring when synchronizing to the synchronization context using:



var result = asyncMethod().Result; 
var result = asyncMethod().GetAwaiter().GetResult();


instead of



var result = await asyncMethod();


(read Stephen Cleary blogpost for more info)



Since the synchronization context has been removed in .NetCore. Does this mean that the above methods are now safe to use?







c# asynchronous asp.net-core async-await






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 12 at 15:12









Lillem4n

716




716







  • 2




    I'd go with "marginally less likely to explode and maim you"... they're still hugely problematic and best avoided, with a slight caveat around "unless you have checked, and already know that they completed successfully"
    – Marc Gravell
    Nov 12 at 15:37







  • 1




    @MarcGravell: But if you already know that they completed successfully then await does not yield, so in that case you might as well just use await.
    – Eric Lippert
    Nov 12 at 18:52






  • 3




    @EricLippert there are cases - especially in IO/perf code - where the state machine overhead is very measurable and a lot of the calls turn out to be sync; in those cases, there are demonstrable benefits in having a pure sync fast path with an async fallback; I acknowledge that this is probably a niche area - and certainly one that impacts library/framework authors a lot more than it impacts application authors: but it is a very real thing; as an aside: local functions work nicely for this case, it turns out - but usually in the proposed "static local function" sense (no capture state)
    – Marc Gravell
    Nov 12 at 19:21













  • 2




    I'd go with "marginally less likely to explode and maim you"... they're still hugely problematic and best avoided, with a slight caveat around "unless you have checked, and already know that they completed successfully"
    – Marc Gravell
    Nov 12 at 15:37







  • 1




    @MarcGravell: But if you already know that they completed successfully then await does not yield, so in that case you might as well just use await.
    – Eric Lippert
    Nov 12 at 18:52






  • 3




    @EricLippert there are cases - especially in IO/perf code - where the state machine overhead is very measurable and a lot of the calls turn out to be sync; in those cases, there are demonstrable benefits in having a pure sync fast path with an async fallback; I acknowledge that this is probably a niche area - and certainly one that impacts library/framework authors a lot more than it impacts application authors: but it is a very real thing; as an aside: local functions work nicely for this case, it turns out - but usually in the proposed "static local function" sense (no capture state)
    – Marc Gravell
    Nov 12 at 19:21








2




2




I'd go with "marginally less likely to explode and maim you"... they're still hugely problematic and best avoided, with a slight caveat around "unless you have checked, and already know that they completed successfully"
– Marc Gravell
Nov 12 at 15:37





I'd go with "marginally less likely to explode and maim you"... they're still hugely problematic and best avoided, with a slight caveat around "unless you have checked, and already know that they completed successfully"
– Marc Gravell
Nov 12 at 15:37





1




1




@MarcGravell: But if you already know that they completed successfully then await does not yield, so in that case you might as well just use await.
– Eric Lippert
Nov 12 at 18:52




@MarcGravell: But if you already know that they completed successfully then await does not yield, so in that case you might as well just use await.
– Eric Lippert
Nov 12 at 18:52




3




3




@EricLippert there are cases - especially in IO/perf code - where the state machine overhead is very measurable and a lot of the calls turn out to be sync; in those cases, there are demonstrable benefits in having a pure sync fast path with an async fallback; I acknowledge that this is probably a niche area - and certainly one that impacts library/framework authors a lot more than it impacts application authors: but it is a very real thing; as an aside: local functions work nicely for this case, it turns out - but usually in the proposed "static local function" sense (no capture state)
– Marc Gravell
Nov 12 at 19:21





@EricLippert there are cases - especially in IO/perf code - where the state machine overhead is very measurable and a lot of the calls turn out to be sync; in those cases, there are demonstrable benefits in having a pure sync fast path with an async fallback; I acknowledge that this is probably a niche area - and certainly one that impacts library/framework authors a lot more than it impacts application authors: but it is a very real thing; as an aside: local functions work nicely for this case, it turns out - but usually in the proposed "static local function" sense (no capture state)
– Marc Gravell
Nov 12 at 19:21













2 Answers
2






active

oldest

votes


















3














Yes and no. It's true that there's no synchronization context in .NET Core, and thereby, one of the major sources of deadlock issues has been eliminated. However, this doesn't mean that deadlocks are totally impossible. Regardless, you should not let good programming practices slide, just because it may not be a big issue in one circumstance any more. ASP.NET Core, in particular, is fully async, so there is no reason to ever use a sync version of a method or simply block on an async task. Use await as you always would and should.






share|improve this answer




















  • I completely agree with you in regards to best practice. However, to keep on topic: Are there any known deadlock issues with these methods in .NetCore now that the synchronization context is gone?
    – Lillem4n
    Nov 12 at 16:19






  • 2




    @Lillem4n Well, Stephen Cleary says no.
    – GSerg
    Nov 12 at 16:25










  • @GSerg that actually solves my question! Thank you!
    – Lillem4n
    Nov 12 at 16:41






  • 2




    @Lillem4n While you're mostly safe from deadlocks, you can still experience threadpool starvation labs.criteo.com/2018/10/…
    – Kevin Gosse
    Nov 12 at 23:08






  • 1




    @KevinGosse Great post, thank you!
    – Lillem4n
    Nov 13 at 9:14


















1














You Can Block on Async Code - But You Shouldn’t



The first and most obvious consequence is that there’s no context captured by await. This means that blocking on asynchronous code won’t cause a deadlock. You can use Task.GetAwaiter().GetResult() (or Task.Wait or Task.Result) without fear of deadlock.
However, you shouldn’t. Because the moment you block on asynchronous code, you’re giving up every benefit of asynchronous code in the first place. The enhanced scalability of asynchronous handlers is nullified as soon as you block a thread.
There were a couple of scenarios in (legacy) ASP.NET where blocking was unfortunately necessary: ASP.NET MVC filters and child actions. However, in ASP.NET Core, the entire pipeline is fully asynchronous; both filters and view components execute asynchronously.
In conclusion, ideally you should strive to use async all the way; but if your code needs to, it can block without danger.



-Extract from blogpost by Stephen Cleary



Credit to GSerg for finding the post



However, you might encounter thread pool starvation



http://labs.criteo.com/2018/10/net-threadpool-starvation-and-how-queuing-makes-it-worse/






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%2f53265020%2fc-sharp-async-await-deadlock-problem-gone-in-netcore%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    Yes and no. It's true that there's no synchronization context in .NET Core, and thereby, one of the major sources of deadlock issues has been eliminated. However, this doesn't mean that deadlocks are totally impossible. Regardless, you should not let good programming practices slide, just because it may not be a big issue in one circumstance any more. ASP.NET Core, in particular, is fully async, so there is no reason to ever use a sync version of a method or simply block on an async task. Use await as you always would and should.






    share|improve this answer




















    • I completely agree with you in regards to best practice. However, to keep on topic: Are there any known deadlock issues with these methods in .NetCore now that the synchronization context is gone?
      – Lillem4n
      Nov 12 at 16:19






    • 2




      @Lillem4n Well, Stephen Cleary says no.
      – GSerg
      Nov 12 at 16:25










    • @GSerg that actually solves my question! Thank you!
      – Lillem4n
      Nov 12 at 16:41






    • 2




      @Lillem4n While you're mostly safe from deadlocks, you can still experience threadpool starvation labs.criteo.com/2018/10/…
      – Kevin Gosse
      Nov 12 at 23:08






    • 1




      @KevinGosse Great post, thank you!
      – Lillem4n
      Nov 13 at 9:14















    3














    Yes and no. It's true that there's no synchronization context in .NET Core, and thereby, one of the major sources of deadlock issues has been eliminated. However, this doesn't mean that deadlocks are totally impossible. Regardless, you should not let good programming practices slide, just because it may not be a big issue in one circumstance any more. ASP.NET Core, in particular, is fully async, so there is no reason to ever use a sync version of a method or simply block on an async task. Use await as you always would and should.






    share|improve this answer




















    • I completely agree with you in regards to best practice. However, to keep on topic: Are there any known deadlock issues with these methods in .NetCore now that the synchronization context is gone?
      – Lillem4n
      Nov 12 at 16:19






    • 2




      @Lillem4n Well, Stephen Cleary says no.
      – GSerg
      Nov 12 at 16:25










    • @GSerg that actually solves my question! Thank you!
      – Lillem4n
      Nov 12 at 16:41






    • 2




      @Lillem4n While you're mostly safe from deadlocks, you can still experience threadpool starvation labs.criteo.com/2018/10/…
      – Kevin Gosse
      Nov 12 at 23:08






    • 1




      @KevinGosse Great post, thank you!
      – Lillem4n
      Nov 13 at 9:14













    3












    3








    3






    Yes and no. It's true that there's no synchronization context in .NET Core, and thereby, one of the major sources of deadlock issues has been eliminated. However, this doesn't mean that deadlocks are totally impossible. Regardless, you should not let good programming practices slide, just because it may not be a big issue in one circumstance any more. ASP.NET Core, in particular, is fully async, so there is no reason to ever use a sync version of a method or simply block on an async task. Use await as you always would and should.






    share|improve this answer












    Yes and no. It's true that there's no synchronization context in .NET Core, and thereby, one of the major sources of deadlock issues has been eliminated. However, this doesn't mean that deadlocks are totally impossible. Regardless, you should not let good programming practices slide, just because it may not be a big issue in one circumstance any more. ASP.NET Core, in particular, is fully async, so there is no reason to ever use a sync version of a method or simply block on an async task. Use await as you always would and should.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 12 at 15:22









    Chris Pratt

    151k20233298




    151k20233298











    • I completely agree with you in regards to best practice. However, to keep on topic: Are there any known deadlock issues with these methods in .NetCore now that the synchronization context is gone?
      – Lillem4n
      Nov 12 at 16:19






    • 2




      @Lillem4n Well, Stephen Cleary says no.
      – GSerg
      Nov 12 at 16:25










    • @GSerg that actually solves my question! Thank you!
      – Lillem4n
      Nov 12 at 16:41






    • 2




      @Lillem4n While you're mostly safe from deadlocks, you can still experience threadpool starvation labs.criteo.com/2018/10/…
      – Kevin Gosse
      Nov 12 at 23:08






    • 1




      @KevinGosse Great post, thank you!
      – Lillem4n
      Nov 13 at 9:14
















    • I completely agree with you in regards to best practice. However, to keep on topic: Are there any known deadlock issues with these methods in .NetCore now that the synchronization context is gone?
      – Lillem4n
      Nov 12 at 16:19






    • 2




      @Lillem4n Well, Stephen Cleary says no.
      – GSerg
      Nov 12 at 16:25










    • @GSerg that actually solves my question! Thank you!
      – Lillem4n
      Nov 12 at 16:41






    • 2




      @Lillem4n While you're mostly safe from deadlocks, you can still experience threadpool starvation labs.criteo.com/2018/10/…
      – Kevin Gosse
      Nov 12 at 23:08






    • 1




      @KevinGosse Great post, thank you!
      – Lillem4n
      Nov 13 at 9:14















    I completely agree with you in regards to best practice. However, to keep on topic: Are there any known deadlock issues with these methods in .NetCore now that the synchronization context is gone?
    – Lillem4n
    Nov 12 at 16:19




    I completely agree with you in regards to best practice. However, to keep on topic: Are there any known deadlock issues with these methods in .NetCore now that the synchronization context is gone?
    – Lillem4n
    Nov 12 at 16:19




    2




    2




    @Lillem4n Well, Stephen Cleary says no.
    – GSerg
    Nov 12 at 16:25




    @Lillem4n Well, Stephen Cleary says no.
    – GSerg
    Nov 12 at 16:25












    @GSerg that actually solves my question! Thank you!
    – Lillem4n
    Nov 12 at 16:41




    @GSerg that actually solves my question! Thank you!
    – Lillem4n
    Nov 12 at 16:41




    2




    2




    @Lillem4n While you're mostly safe from deadlocks, you can still experience threadpool starvation labs.criteo.com/2018/10/…
    – Kevin Gosse
    Nov 12 at 23:08




    @Lillem4n While you're mostly safe from deadlocks, you can still experience threadpool starvation labs.criteo.com/2018/10/…
    – Kevin Gosse
    Nov 12 at 23:08




    1




    1




    @KevinGosse Great post, thank you!
    – Lillem4n
    Nov 13 at 9:14




    @KevinGosse Great post, thank you!
    – Lillem4n
    Nov 13 at 9:14













    1














    You Can Block on Async Code - But You Shouldn’t



    The first and most obvious consequence is that there’s no context captured by await. This means that blocking on asynchronous code won’t cause a deadlock. You can use Task.GetAwaiter().GetResult() (or Task.Wait or Task.Result) without fear of deadlock.
    However, you shouldn’t. Because the moment you block on asynchronous code, you’re giving up every benefit of asynchronous code in the first place. The enhanced scalability of asynchronous handlers is nullified as soon as you block a thread.
    There were a couple of scenarios in (legacy) ASP.NET where blocking was unfortunately necessary: ASP.NET MVC filters and child actions. However, in ASP.NET Core, the entire pipeline is fully asynchronous; both filters and view components execute asynchronously.
    In conclusion, ideally you should strive to use async all the way; but if your code needs to, it can block without danger.



    -Extract from blogpost by Stephen Cleary



    Credit to GSerg for finding the post



    However, you might encounter thread pool starvation



    http://labs.criteo.com/2018/10/net-threadpool-starvation-and-how-queuing-makes-it-worse/






    share|improve this answer



























      1














      You Can Block on Async Code - But You Shouldn’t



      The first and most obvious consequence is that there’s no context captured by await. This means that blocking on asynchronous code won’t cause a deadlock. You can use Task.GetAwaiter().GetResult() (or Task.Wait or Task.Result) without fear of deadlock.
      However, you shouldn’t. Because the moment you block on asynchronous code, you’re giving up every benefit of asynchronous code in the first place. The enhanced scalability of asynchronous handlers is nullified as soon as you block a thread.
      There were a couple of scenarios in (legacy) ASP.NET where blocking was unfortunately necessary: ASP.NET MVC filters and child actions. However, in ASP.NET Core, the entire pipeline is fully asynchronous; both filters and view components execute asynchronously.
      In conclusion, ideally you should strive to use async all the way; but if your code needs to, it can block without danger.



      -Extract from blogpost by Stephen Cleary



      Credit to GSerg for finding the post



      However, you might encounter thread pool starvation



      http://labs.criteo.com/2018/10/net-threadpool-starvation-and-how-queuing-makes-it-worse/






      share|improve this answer

























        1












        1








        1






        You Can Block on Async Code - But You Shouldn’t



        The first and most obvious consequence is that there’s no context captured by await. This means that blocking on asynchronous code won’t cause a deadlock. You can use Task.GetAwaiter().GetResult() (or Task.Wait or Task.Result) without fear of deadlock.
        However, you shouldn’t. Because the moment you block on asynchronous code, you’re giving up every benefit of asynchronous code in the first place. The enhanced scalability of asynchronous handlers is nullified as soon as you block a thread.
        There were a couple of scenarios in (legacy) ASP.NET where blocking was unfortunately necessary: ASP.NET MVC filters and child actions. However, in ASP.NET Core, the entire pipeline is fully asynchronous; both filters and view components execute asynchronously.
        In conclusion, ideally you should strive to use async all the way; but if your code needs to, it can block without danger.



        -Extract from blogpost by Stephen Cleary



        Credit to GSerg for finding the post



        However, you might encounter thread pool starvation



        http://labs.criteo.com/2018/10/net-threadpool-starvation-and-how-queuing-makes-it-worse/






        share|improve this answer














        You Can Block on Async Code - But You Shouldn’t



        The first and most obvious consequence is that there’s no context captured by await. This means that blocking on asynchronous code won’t cause a deadlock. You can use Task.GetAwaiter().GetResult() (or Task.Wait or Task.Result) without fear of deadlock.
        However, you shouldn’t. Because the moment you block on asynchronous code, you’re giving up every benefit of asynchronous code in the first place. The enhanced scalability of asynchronous handlers is nullified as soon as you block a thread.
        There were a couple of scenarios in (legacy) ASP.NET where blocking was unfortunately necessary: ASP.NET MVC filters and child actions. However, in ASP.NET Core, the entire pipeline is fully asynchronous; both filters and view components execute asynchronously.
        In conclusion, ideally you should strive to use async all the way; but if your code needs to, it can block without danger.



        -Extract from blogpost by Stephen Cleary



        Credit to GSerg for finding the post



        However, you might encounter thread pool starvation



        http://labs.criteo.com/2018/10/net-threadpool-starvation-and-how-queuing-makes-it-worse/







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 13 at 9:03

























        answered Nov 12 at 16:46









        Lillem4n

        716




        716



























            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.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • 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%2f53265020%2fc-sharp-async-await-deadlock-problem-gone-in-netcore%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







            這個網誌中的熱門文章

            How to read a connectionString WITH PROVIDER in .NET Core?

            In R, how to develop a multiplot heatmap.2 figure showing key labels successfully

            Museum of Modern and Contemporary Art of Trento and Rovereto