ConfigureAwait(false) - Does the continuation always run on different thread?
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 returnnull
.
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
add a comment |
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 returnnull
.
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
add a comment |
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 returnnull
.
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
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 returnnull
.
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
c# asp.net .net asp.net-web-api async-await
asked Nov 24 '18 at 9:14
MarkkknkMarkkknk
16918
16918
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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.
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%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
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 24 '18 at 10:09
sellotapesellotape
5,62821619
5,62821619
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.
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%2f53456754%2fconfigureawaitfalse-does-the-continuation-always-run-on-different-thread%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