C# Async await deadlock problem gone in .NetCore?
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
add a comment |
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
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 '18 at 15:37
1
@MarcGravell: But if you already know that they completed successfully thenawait
does not yield, so in that case you might as well just useawait
.
– Eric Lippert
Nov 12 '18 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 '18 at 19:21
add a comment |
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
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
c# asynchronous asp.net-core async-await
asked Nov 12 '18 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 '18 at 15:37
1
@MarcGravell: But if you already know that they completed successfully thenawait
does not yield, so in that case you might as well just useawait
.
– Eric Lippert
Nov 12 '18 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 '18 at 19:21
add a comment |
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 '18 at 15:37
1
@MarcGravell: But if you already know that they completed successfully thenawait
does not yield, so in that case you might as well just useawait
.
– Eric Lippert
Nov 12 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 at 19:21
add a comment |
2 Answers
2
active
oldest
votes
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.
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 '18 at 16:19
2
@Lillem4n Well, Stephen Cleary says no.
– GSerg
Nov 12 '18 at 16:25
@GSerg that actually solves my question! Thank you!
– Lillem4n
Nov 12 '18 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 '18 at 23:08
1
@KevinGosse Great post, thank you!
– Lillem4n
Nov 13 '18 at 9:14
add a comment |
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/
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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 '18 at 16:19
2
@Lillem4n Well, Stephen Cleary says no.
– GSerg
Nov 12 '18 at 16:25
@GSerg that actually solves my question! Thank you!
– Lillem4n
Nov 12 '18 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 '18 at 23:08
1
@KevinGosse Great post, thank you!
– Lillem4n
Nov 13 '18 at 9:14
add a comment |
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.
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 '18 at 16:19
2
@Lillem4n Well, Stephen Cleary says no.
– GSerg
Nov 12 '18 at 16:25
@GSerg that actually solves my question! Thank you!
– Lillem4n
Nov 12 '18 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 '18 at 23:08
1
@KevinGosse Great post, thank you!
– Lillem4n
Nov 13 '18 at 9:14
add a comment |
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.
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.
answered Nov 12 '18 at 15:22
Chris Pratt
152k20233298
152k20233298
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 '18 at 16:19
2
@Lillem4n Well, Stephen Cleary says no.
– GSerg
Nov 12 '18 at 16:25
@GSerg that actually solves my question! Thank you!
– Lillem4n
Nov 12 '18 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 '18 at 23:08
1
@KevinGosse Great post, thank you!
– Lillem4n
Nov 13 '18 at 9:14
add a comment |
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 '18 at 16:19
2
@Lillem4n Well, Stephen Cleary says no.
– GSerg
Nov 12 '18 at 16:25
@GSerg that actually solves my question! Thank you!
– Lillem4n
Nov 12 '18 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 '18 at 23:08
1
@KevinGosse Great post, thank you!
– Lillem4n
Nov 13 '18 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 '18 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 '18 at 16:19
2
2
@Lillem4n Well, Stephen Cleary says no.
– GSerg
Nov 12 '18 at 16:25
@Lillem4n Well, Stephen Cleary says no.
– GSerg
Nov 12 '18 at 16:25
@GSerg that actually solves my question! Thank you!
– Lillem4n
Nov 12 '18 at 16:41
@GSerg that actually solves my question! Thank you!
– Lillem4n
Nov 12 '18 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 '18 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 '18 at 23:08
1
1
@KevinGosse Great post, thank you!
– Lillem4n
Nov 13 '18 at 9:14
@KevinGosse Great post, thank you!
– Lillem4n
Nov 13 '18 at 9:14
add a comment |
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/
add a comment |
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/
add a comment |
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/
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/
edited Nov 13 '18 at 9:03
answered Nov 12 '18 at 16:46
Lillem4n
716
716
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 '18 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 useawait
.– Eric Lippert
Nov 12 '18 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 '18 at 19:21