In .NET, are async methods exclusively those with the async keyword?
I've been learning about HttpClient (consuming API's in .NET in general), and therefore about async programming. I'm still pretty lost right now, so trying to clear some things up. One question I can't seem to find an answer to - are asynchronous methods implemented exclusively using the async keyword?
I understand that you could (theoretically) create synchronous methods using async programming, but how do you recognize that? For example, from this link and this example:
public string GetReleases(string url)
{
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add(RequestConstants.UserAgent, RequestConstants.UserAgentValue);
var response = httpClient.GetStringAsync(new Uri(url)).Result;
return response;
}
}
The author says:
For the simplicity’s sake, I implemented it synchronously
But how do I recognize it is synchronous? Is it solely because the method is not defined with async Task, for example:
public async Task<string> GetReleases(string url)
Does that mean that in this HttpClient tutorial, this example is also not asynchronous:
// GET: Student
public ActionResult Index()
{
IEnumerable<StudentViewModel> students = null;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:64189/api/");
//HTTP GET
var responseTask = client.GetAsync("student");
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsAsync<IList<StudentViewModel>>();
readTask.Wait();
students = readTask.Result;
}
else //web api sent error response
{
//log response status here..
students = Enumerable.Empty<StudentViewModel>();
ModelState.AddModelError(string.Empty, "Server error. Please contact administrator.");
}
}
return View(students);
}
So to sum up, my questions are:
- Is async programming (in .NET), and async methods, implemented exclusively using async and void/Task/Task?
- If not, how else, and if so, how do I recognize "true" asynchronous methods compared to synchronous methods implemented using asychronous principles (like the example above?)
- Why then did the above examples use "sync through async", since from everything I've read everyone says to NEVER do that? Are they just bad examples, or for simplicity sake (even so, shouldn't "the correct way" > "simplicity"? Would it be ok to use this in situations where, e.g., I have very simple code and want to avoid threading/deadlock issues, since I'm not comfortable with async programming just yet?
c# .net asynchronous httpclient
New contributor
|
show 4 more comments
I've been learning about HttpClient (consuming API's in .NET in general), and therefore about async programming. I'm still pretty lost right now, so trying to clear some things up. One question I can't seem to find an answer to - are asynchronous methods implemented exclusively using the async keyword?
I understand that you could (theoretically) create synchronous methods using async programming, but how do you recognize that? For example, from this link and this example:
public string GetReleases(string url)
{
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add(RequestConstants.UserAgent, RequestConstants.UserAgentValue);
var response = httpClient.GetStringAsync(new Uri(url)).Result;
return response;
}
}
The author says:
For the simplicity’s sake, I implemented it synchronously
But how do I recognize it is synchronous? Is it solely because the method is not defined with async Task, for example:
public async Task<string> GetReleases(string url)
Does that mean that in this HttpClient tutorial, this example is also not asynchronous:
// GET: Student
public ActionResult Index()
{
IEnumerable<StudentViewModel> students = null;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:64189/api/");
//HTTP GET
var responseTask = client.GetAsync("student");
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsAsync<IList<StudentViewModel>>();
readTask.Wait();
students = readTask.Result;
}
else //web api sent error response
{
//log response status here..
students = Enumerable.Empty<StudentViewModel>();
ModelState.AddModelError(string.Empty, "Server error. Please contact administrator.");
}
}
return View(students);
}
So to sum up, my questions are:
- Is async programming (in .NET), and async methods, implemented exclusively using async and void/Task/Task?
- If not, how else, and if so, how do I recognize "true" asynchronous methods compared to synchronous methods implemented using asychronous principles (like the example above?)
- Why then did the above examples use "sync through async", since from everything I've read everyone says to NEVER do that? Are they just bad examples, or for simplicity sake (even so, shouldn't "the correct way" > "simplicity"? Would it be ok to use this in situations where, e.g., I have very simple code and want to avoid threading/deadlock issues, since I'm not comfortable with async programming just yet?
c# .net asynchronous httpclient
New contributor
"For simplicity's sake" he implemented it wrong, in more than 1 aspect. It's a bad example (first snippet "GetReleases").
– Fildor
yesterday
1
are asynchronous methods implemented exclusively using the async keyword?
- no, the keywordasync
means "I may useawait
inside this method". In order to be awaitable, a method must returnTask
, whether or not it itself is marked asasync
.
– GSerg
yesterday
1
To add to GSerg: Neither of which will tell you 100% that the function will be executed asynchronously, though.
– Fildor
yesterday
2
I would suggest blog.stephencleary.com/2012/02/async-and-await.html as a starting point, and then follow links from there (specifically, don't miss blog.stephencleary.com/2012/07/dont-block-on-async-code.html).
– GSerg
yesterday
async essentially is a keyword that implies that you want to use asynchronous programming. (aka, it's a keyword that refers to a pattern -ish)
– Dennis Vanhout
yesterday
|
show 4 more comments
I've been learning about HttpClient (consuming API's in .NET in general), and therefore about async programming. I'm still pretty lost right now, so trying to clear some things up. One question I can't seem to find an answer to - are asynchronous methods implemented exclusively using the async keyword?
I understand that you could (theoretically) create synchronous methods using async programming, but how do you recognize that? For example, from this link and this example:
public string GetReleases(string url)
{
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add(RequestConstants.UserAgent, RequestConstants.UserAgentValue);
var response = httpClient.GetStringAsync(new Uri(url)).Result;
return response;
}
}
The author says:
For the simplicity’s sake, I implemented it synchronously
But how do I recognize it is synchronous? Is it solely because the method is not defined with async Task, for example:
public async Task<string> GetReleases(string url)
Does that mean that in this HttpClient tutorial, this example is also not asynchronous:
// GET: Student
public ActionResult Index()
{
IEnumerable<StudentViewModel> students = null;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:64189/api/");
//HTTP GET
var responseTask = client.GetAsync("student");
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsAsync<IList<StudentViewModel>>();
readTask.Wait();
students = readTask.Result;
}
else //web api sent error response
{
//log response status here..
students = Enumerable.Empty<StudentViewModel>();
ModelState.AddModelError(string.Empty, "Server error. Please contact administrator.");
}
}
return View(students);
}
So to sum up, my questions are:
- Is async programming (in .NET), and async methods, implemented exclusively using async and void/Task/Task?
- If not, how else, and if so, how do I recognize "true" asynchronous methods compared to synchronous methods implemented using asychronous principles (like the example above?)
- Why then did the above examples use "sync through async", since from everything I've read everyone says to NEVER do that? Are they just bad examples, or for simplicity sake (even so, shouldn't "the correct way" > "simplicity"? Would it be ok to use this in situations where, e.g., I have very simple code and want to avoid threading/deadlock issues, since I'm not comfortable with async programming just yet?
c# .net asynchronous httpclient
New contributor
I've been learning about HttpClient (consuming API's in .NET in general), and therefore about async programming. I'm still pretty lost right now, so trying to clear some things up. One question I can't seem to find an answer to - are asynchronous methods implemented exclusively using the async keyword?
I understand that you could (theoretically) create synchronous methods using async programming, but how do you recognize that? For example, from this link and this example:
public string GetReleases(string url)
{
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add(RequestConstants.UserAgent, RequestConstants.UserAgentValue);
var response = httpClient.GetStringAsync(new Uri(url)).Result;
return response;
}
}
The author says:
For the simplicity’s sake, I implemented it synchronously
But how do I recognize it is synchronous? Is it solely because the method is not defined with async Task, for example:
public async Task<string> GetReleases(string url)
Does that mean that in this HttpClient tutorial, this example is also not asynchronous:
// GET: Student
public ActionResult Index()
{
IEnumerable<StudentViewModel> students = null;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:64189/api/");
//HTTP GET
var responseTask = client.GetAsync("student");
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsAsync<IList<StudentViewModel>>();
readTask.Wait();
students = readTask.Result;
}
else //web api sent error response
{
//log response status here..
students = Enumerable.Empty<StudentViewModel>();
ModelState.AddModelError(string.Empty, "Server error. Please contact administrator.");
}
}
return View(students);
}
So to sum up, my questions are:
- Is async programming (in .NET), and async methods, implemented exclusively using async and void/Task/Task?
- If not, how else, and if so, how do I recognize "true" asynchronous methods compared to synchronous methods implemented using asychronous principles (like the example above?)
- Why then did the above examples use "sync through async", since from everything I've read everyone says to NEVER do that? Are they just bad examples, or for simplicity sake (even so, shouldn't "the correct way" > "simplicity"? Would it be ok to use this in situations where, e.g., I have very simple code and want to avoid threading/deadlock issues, since I'm not comfortable with async programming just yet?
c# .net asynchronous httpclient
c# .net asynchronous httpclient
New contributor
New contributor
New contributor
asked yesterday
vpDevvpDev
163
163
New contributor
New contributor
"For simplicity's sake" he implemented it wrong, in more than 1 aspect. It's a bad example (first snippet "GetReleases").
– Fildor
yesterday
1
are asynchronous methods implemented exclusively using the async keyword?
- no, the keywordasync
means "I may useawait
inside this method". In order to be awaitable, a method must returnTask
, whether or not it itself is marked asasync
.
– GSerg
yesterday
1
To add to GSerg: Neither of which will tell you 100% that the function will be executed asynchronously, though.
– Fildor
yesterday
2
I would suggest blog.stephencleary.com/2012/02/async-and-await.html as a starting point, and then follow links from there (specifically, don't miss blog.stephencleary.com/2012/07/dont-block-on-async-code.html).
– GSerg
yesterday
async essentially is a keyword that implies that you want to use asynchronous programming. (aka, it's a keyword that refers to a pattern -ish)
– Dennis Vanhout
yesterday
|
show 4 more comments
"For simplicity's sake" he implemented it wrong, in more than 1 aspect. It's a bad example (first snippet "GetReleases").
– Fildor
yesterday
1
are asynchronous methods implemented exclusively using the async keyword?
- no, the keywordasync
means "I may useawait
inside this method". In order to be awaitable, a method must returnTask
, whether or not it itself is marked asasync
.
– GSerg
yesterday
1
To add to GSerg: Neither of which will tell you 100% that the function will be executed asynchronously, though.
– Fildor
yesterday
2
I would suggest blog.stephencleary.com/2012/02/async-and-await.html as a starting point, and then follow links from there (specifically, don't miss blog.stephencleary.com/2012/07/dont-block-on-async-code.html).
– GSerg
yesterday
async essentially is a keyword that implies that you want to use asynchronous programming. (aka, it's a keyword that refers to a pattern -ish)
– Dennis Vanhout
yesterday
"For simplicity's sake" he implemented it wrong, in more than 1 aspect. It's a bad example (first snippet "GetReleases").
– Fildor
yesterday
"For simplicity's sake" he implemented it wrong, in more than 1 aspect. It's a bad example (first snippet "GetReleases").
– Fildor
yesterday
1
1
are asynchronous methods implemented exclusively using the async keyword?
- no, the keyword async
means "I may use await
inside this method". In order to be awaitable, a method must return Task
, whether or not it itself is marked as async
.– GSerg
yesterday
are asynchronous methods implemented exclusively using the async keyword?
- no, the keyword async
means "I may use await
inside this method". In order to be awaitable, a method must return Task
, whether or not it itself is marked as async
.– GSerg
yesterday
1
1
To add to GSerg: Neither of which will tell you 100% that the function will be executed asynchronously, though.
– Fildor
yesterday
To add to GSerg: Neither of which will tell you 100% that the function will be executed asynchronously, though.
– Fildor
yesterday
2
2
I would suggest blog.stephencleary.com/2012/02/async-and-await.html as a starting point, and then follow links from there (specifically, don't miss blog.stephencleary.com/2012/07/dont-block-on-async-code.html).
– GSerg
yesterday
I would suggest blog.stephencleary.com/2012/02/async-and-await.html as a starting point, and then follow links from there (specifically, don't miss blog.stephencleary.com/2012/07/dont-block-on-async-code.html).
– GSerg
yesterday
async essentially is a keyword that implies that you want to use asynchronous programming. (aka, it's a keyword that refers to a pattern -ish)
– Dennis Vanhout
yesterday
async essentially is a keyword that implies that you want to use asynchronous programming. (aka, it's a keyword that refers to a pattern -ish)
– Dennis Vanhout
yesterday
|
show 4 more comments
3 Answers
3
active
oldest
votes
how can I recognize truely async/sync methods?
You can't. Not really. You can spot methods that are potentially async, but little else can be learned without consulting documentation or the implementation of those methods.
So, you can examine a method's return type. If it's void
, you don't know much. If it's Task
, Task<T>
, ValueTask<T>
or any other awaitable type1, then the method may be asynchronous. But bear in mind, the method signature may be fixed because the type inherited the method from a base class or it's implementing an interface; So whilst the method has the potential to be async, the actual implementation of that method may be completely synchronous.
Or, the method may have the potential to be asynchronous but may have particular control flows which lead to it behaving synchronously2. These may be e.g. that if certain conditions are true, the method already has the answer, so it returns it straight away. Otherwise it goes off and does something async - as one example.
If the return type isn't awaitable and it's non-void, all you can actually reason about the method is that, at the point at which it returns, it's supplied some value for that return type3. There's no way to reason about any other work that may have been started by that method - only that if it's done something like that, it doesn't intend for you to be able to discover when that work has completed.
If you're looking at the implementation of a method and asking yourself "is this implementation async" then the important thing is to work out what this code makes happen after control is returned back to the caller.
When is control returned back to the caller?
- When we hit a
return
- When we hit an
await
, maybe
When we hit an await
, we only return control back to the caller4 if the awaitable that we're await
ing isn't complete yet. So we have to find out where that awaitable came from and, if it came from calling another method, we have to start again from scratch in considering what that method does.
If the method contains await
s then it's usually safest to say that it's potentially async - but bear in mind the above possibilities about already completed awaitables and early return
s.
If it's not async
/await
, what else might it have done? Well, if it's working with Task
s, it may have created one or more of those tasks to represent it's ongoing work. It may have scheduled more code to run via ContinueWith
.
If it's not working with Task
s directly, hasn't called something else that is potentially async, hasn't cause a new Thread
to be created and isn't needlessly obfuscated, it's probably synchronous.
Would it be ok to use this in situations where, e.g., I have very simple code and want to avoid threading/deadlock issues, since I'm not comfortable with async programming just yet?
The sync over async patterns shown in the examples in your question are more prone to deadlocks than working with async
/await
. Why? Because they block the current thread waiting for other things to happen. But the current thread or resources that it has locked may be special - and the actual async tasks that it's invoked may need to gain access to that same thread/resource before they can complete. Classic deadlock.
1Awaitable is one of a number of places where C# uses "duck typing". If there's a method available (instance or extension) called GetAwaiter
that returns a type with the right shape, it's awaitable. So despite the fact that you'll probably never see one, be aware that custom awaitables are possible in the language.
2"Hot path" optimizations come to mind.
3And out
/ref
parameters. Of course, if it has those it won't be an async method implemented via the async
/await
keywords but it may still have some asynchronous behaviour.
4If we've already yielded control back to the caller during an earlier await
, we won't return control back to the caller at later await
s, but we'll be returning it to "something" that isn't our code.
add a comment |
If a method returns a
Task
orTask<T>
(with exception to void in case of event handler) then it can be awaited and hence it can be asynchronous.async
keyword is only an indication that it mayawait
somewhere for another awaitable. Based on the control flow,async
may return without actually awaiting anything.
Asynchronous programming is not a new thing, it has existed in many forms like callbacks, Invokes etc.Examples you have provided are not using async await pattern properly. Microsoft has provided naming convention (Async Suffix) and
Task<T>
,Task
as types for async programming. So if you see some method returningTask<T>
orTask
and Method name has suffix "Async" then you can consider it asynchronous. Although suffix thing is not required by compiler, it helps in differentiating it from its synchronous counterpart. (Read
vsReadAsync
)They are bad examples, those action should be marked as async and all the Async methods should be awaited for result. There can be an exception in some console program where main can't be async.
Please read Stephen Cleary blog on async await
add a comment |
An asynchronous method in C# can return void
, Task
or Task<T>
, where void
should be avoided in general because it cannot be awaited.
As a convention asynchronous methods should be called DoSomethingAsync()
The async
keyword, however, is an implementation detail and does not belong to the API. This keyword is only required if you use an await
in the method body. But that need not be the case. You could simply delegate to another asynchronous method, without the need to mark the method as async
and using an await
.
So 'true' asynchronous methods should be recognizable by the Async
suffix of the method name, however, you can't be sure the implementor actually uses naturally asynchronous operations or even runs synchronously some parts or the whole method.
In the example he made the method synchronously by putting .Result
at the end of GetStringAsync
by the Async prefix of the method name
- unless the author did not bother to follow that convention, or unless it is a legacy method the name for which was selected before introduction ofawait
(yes, they exist in .NET).
– GSerg
yesterday
2
Postfix , that is. Prefix would be "AsyncDoSomething".
– Fildor
yesterday
3
Suffix, since we're nit-picking
– Matthew Evans
yesterday
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
});
}
});
vpDev is a new contributor. Be nice, and check out our Code of Conduct.
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%2f54251841%2fin-net-are-async-methods-exclusively-those-with-the-async-keyword%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
how can I recognize truely async/sync methods?
You can't. Not really. You can spot methods that are potentially async, but little else can be learned without consulting documentation or the implementation of those methods.
So, you can examine a method's return type. If it's void
, you don't know much. If it's Task
, Task<T>
, ValueTask<T>
or any other awaitable type1, then the method may be asynchronous. But bear in mind, the method signature may be fixed because the type inherited the method from a base class or it's implementing an interface; So whilst the method has the potential to be async, the actual implementation of that method may be completely synchronous.
Or, the method may have the potential to be asynchronous but may have particular control flows which lead to it behaving synchronously2. These may be e.g. that if certain conditions are true, the method already has the answer, so it returns it straight away. Otherwise it goes off and does something async - as one example.
If the return type isn't awaitable and it's non-void, all you can actually reason about the method is that, at the point at which it returns, it's supplied some value for that return type3. There's no way to reason about any other work that may have been started by that method - only that if it's done something like that, it doesn't intend for you to be able to discover when that work has completed.
If you're looking at the implementation of a method and asking yourself "is this implementation async" then the important thing is to work out what this code makes happen after control is returned back to the caller.
When is control returned back to the caller?
- When we hit a
return
- When we hit an
await
, maybe
When we hit an await
, we only return control back to the caller4 if the awaitable that we're await
ing isn't complete yet. So we have to find out where that awaitable came from and, if it came from calling another method, we have to start again from scratch in considering what that method does.
If the method contains await
s then it's usually safest to say that it's potentially async - but bear in mind the above possibilities about already completed awaitables and early return
s.
If it's not async
/await
, what else might it have done? Well, if it's working with Task
s, it may have created one or more of those tasks to represent it's ongoing work. It may have scheduled more code to run via ContinueWith
.
If it's not working with Task
s directly, hasn't called something else that is potentially async, hasn't cause a new Thread
to be created and isn't needlessly obfuscated, it's probably synchronous.
Would it be ok to use this in situations where, e.g., I have very simple code and want to avoid threading/deadlock issues, since I'm not comfortable with async programming just yet?
The sync over async patterns shown in the examples in your question are more prone to deadlocks than working with async
/await
. Why? Because they block the current thread waiting for other things to happen. But the current thread or resources that it has locked may be special - and the actual async tasks that it's invoked may need to gain access to that same thread/resource before they can complete. Classic deadlock.
1Awaitable is one of a number of places where C# uses "duck typing". If there's a method available (instance or extension) called GetAwaiter
that returns a type with the right shape, it's awaitable. So despite the fact that you'll probably never see one, be aware that custom awaitables are possible in the language.
2"Hot path" optimizations come to mind.
3And out
/ref
parameters. Of course, if it has those it won't be an async method implemented via the async
/await
keywords but it may still have some asynchronous behaviour.
4If we've already yielded control back to the caller during an earlier await
, we won't return control back to the caller at later await
s, but we'll be returning it to "something" that isn't our code.
add a comment |
how can I recognize truely async/sync methods?
You can't. Not really. You can spot methods that are potentially async, but little else can be learned without consulting documentation or the implementation of those methods.
So, you can examine a method's return type. If it's void
, you don't know much. If it's Task
, Task<T>
, ValueTask<T>
or any other awaitable type1, then the method may be asynchronous. But bear in mind, the method signature may be fixed because the type inherited the method from a base class or it's implementing an interface; So whilst the method has the potential to be async, the actual implementation of that method may be completely synchronous.
Or, the method may have the potential to be asynchronous but may have particular control flows which lead to it behaving synchronously2. These may be e.g. that if certain conditions are true, the method already has the answer, so it returns it straight away. Otherwise it goes off and does something async - as one example.
If the return type isn't awaitable and it's non-void, all you can actually reason about the method is that, at the point at which it returns, it's supplied some value for that return type3. There's no way to reason about any other work that may have been started by that method - only that if it's done something like that, it doesn't intend for you to be able to discover when that work has completed.
If you're looking at the implementation of a method and asking yourself "is this implementation async" then the important thing is to work out what this code makes happen after control is returned back to the caller.
When is control returned back to the caller?
- When we hit a
return
- When we hit an
await
, maybe
When we hit an await
, we only return control back to the caller4 if the awaitable that we're await
ing isn't complete yet. So we have to find out where that awaitable came from and, if it came from calling another method, we have to start again from scratch in considering what that method does.
If the method contains await
s then it's usually safest to say that it's potentially async - but bear in mind the above possibilities about already completed awaitables and early return
s.
If it's not async
/await
, what else might it have done? Well, if it's working with Task
s, it may have created one or more of those tasks to represent it's ongoing work. It may have scheduled more code to run via ContinueWith
.
If it's not working with Task
s directly, hasn't called something else that is potentially async, hasn't cause a new Thread
to be created and isn't needlessly obfuscated, it's probably synchronous.
Would it be ok to use this in situations where, e.g., I have very simple code and want to avoid threading/deadlock issues, since I'm not comfortable with async programming just yet?
The sync over async patterns shown in the examples in your question are more prone to deadlocks than working with async
/await
. Why? Because they block the current thread waiting for other things to happen. But the current thread or resources that it has locked may be special - and the actual async tasks that it's invoked may need to gain access to that same thread/resource before they can complete. Classic deadlock.
1Awaitable is one of a number of places where C# uses "duck typing". If there's a method available (instance or extension) called GetAwaiter
that returns a type with the right shape, it's awaitable. So despite the fact that you'll probably never see one, be aware that custom awaitables are possible in the language.
2"Hot path" optimizations come to mind.
3And out
/ref
parameters. Of course, if it has those it won't be an async method implemented via the async
/await
keywords but it may still have some asynchronous behaviour.
4If we've already yielded control back to the caller during an earlier await
, we won't return control back to the caller at later await
s, but we'll be returning it to "something" that isn't our code.
add a comment |
how can I recognize truely async/sync methods?
You can't. Not really. You can spot methods that are potentially async, but little else can be learned without consulting documentation or the implementation of those methods.
So, you can examine a method's return type. If it's void
, you don't know much. If it's Task
, Task<T>
, ValueTask<T>
or any other awaitable type1, then the method may be asynchronous. But bear in mind, the method signature may be fixed because the type inherited the method from a base class or it's implementing an interface; So whilst the method has the potential to be async, the actual implementation of that method may be completely synchronous.
Or, the method may have the potential to be asynchronous but may have particular control flows which lead to it behaving synchronously2. These may be e.g. that if certain conditions are true, the method already has the answer, so it returns it straight away. Otherwise it goes off and does something async - as one example.
If the return type isn't awaitable and it's non-void, all you can actually reason about the method is that, at the point at which it returns, it's supplied some value for that return type3. There's no way to reason about any other work that may have been started by that method - only that if it's done something like that, it doesn't intend for you to be able to discover when that work has completed.
If you're looking at the implementation of a method and asking yourself "is this implementation async" then the important thing is to work out what this code makes happen after control is returned back to the caller.
When is control returned back to the caller?
- When we hit a
return
- When we hit an
await
, maybe
When we hit an await
, we only return control back to the caller4 if the awaitable that we're await
ing isn't complete yet. So we have to find out where that awaitable came from and, if it came from calling another method, we have to start again from scratch in considering what that method does.
If the method contains await
s then it's usually safest to say that it's potentially async - but bear in mind the above possibilities about already completed awaitables and early return
s.
If it's not async
/await
, what else might it have done? Well, if it's working with Task
s, it may have created one or more of those tasks to represent it's ongoing work. It may have scheduled more code to run via ContinueWith
.
If it's not working with Task
s directly, hasn't called something else that is potentially async, hasn't cause a new Thread
to be created and isn't needlessly obfuscated, it's probably synchronous.
Would it be ok to use this in situations where, e.g., I have very simple code and want to avoid threading/deadlock issues, since I'm not comfortable with async programming just yet?
The sync over async patterns shown in the examples in your question are more prone to deadlocks than working with async
/await
. Why? Because they block the current thread waiting for other things to happen. But the current thread or resources that it has locked may be special - and the actual async tasks that it's invoked may need to gain access to that same thread/resource before they can complete. Classic deadlock.
1Awaitable is one of a number of places where C# uses "duck typing". If there's a method available (instance or extension) called GetAwaiter
that returns a type with the right shape, it's awaitable. So despite the fact that you'll probably never see one, be aware that custom awaitables are possible in the language.
2"Hot path" optimizations come to mind.
3And out
/ref
parameters. Of course, if it has those it won't be an async method implemented via the async
/await
keywords but it may still have some asynchronous behaviour.
4If we've already yielded control back to the caller during an earlier await
, we won't return control back to the caller at later await
s, but we'll be returning it to "something" that isn't our code.
how can I recognize truely async/sync methods?
You can't. Not really. You can spot methods that are potentially async, but little else can be learned without consulting documentation or the implementation of those methods.
So, you can examine a method's return type. If it's void
, you don't know much. If it's Task
, Task<T>
, ValueTask<T>
or any other awaitable type1, then the method may be asynchronous. But bear in mind, the method signature may be fixed because the type inherited the method from a base class or it's implementing an interface; So whilst the method has the potential to be async, the actual implementation of that method may be completely synchronous.
Or, the method may have the potential to be asynchronous but may have particular control flows which lead to it behaving synchronously2. These may be e.g. that if certain conditions are true, the method already has the answer, so it returns it straight away. Otherwise it goes off and does something async - as one example.
If the return type isn't awaitable and it's non-void, all you can actually reason about the method is that, at the point at which it returns, it's supplied some value for that return type3. There's no way to reason about any other work that may have been started by that method - only that if it's done something like that, it doesn't intend for you to be able to discover when that work has completed.
If you're looking at the implementation of a method and asking yourself "is this implementation async" then the important thing is to work out what this code makes happen after control is returned back to the caller.
When is control returned back to the caller?
- When we hit a
return
- When we hit an
await
, maybe
When we hit an await
, we only return control back to the caller4 if the awaitable that we're await
ing isn't complete yet. So we have to find out where that awaitable came from and, if it came from calling another method, we have to start again from scratch in considering what that method does.
If the method contains await
s then it's usually safest to say that it's potentially async - but bear in mind the above possibilities about already completed awaitables and early return
s.
If it's not async
/await
, what else might it have done? Well, if it's working with Task
s, it may have created one or more of those tasks to represent it's ongoing work. It may have scheduled more code to run via ContinueWith
.
If it's not working with Task
s directly, hasn't called something else that is potentially async, hasn't cause a new Thread
to be created and isn't needlessly obfuscated, it's probably synchronous.
Would it be ok to use this in situations where, e.g., I have very simple code and want to avoid threading/deadlock issues, since I'm not comfortable with async programming just yet?
The sync over async patterns shown in the examples in your question are more prone to deadlocks than working with async
/await
. Why? Because they block the current thread waiting for other things to happen. But the current thread or resources that it has locked may be special - and the actual async tasks that it's invoked may need to gain access to that same thread/resource before they can complete. Classic deadlock.
1Awaitable is one of a number of places where C# uses "duck typing". If there's a method available (instance or extension) called GetAwaiter
that returns a type with the right shape, it's awaitable. So despite the fact that you'll probably never see one, be aware that custom awaitables are possible in the language.
2"Hot path" optimizations come to mind.
3And out
/ref
parameters. Of course, if it has those it won't be an async method implemented via the async
/await
keywords but it may still have some asynchronous behaviour.
4If we've already yielded control back to the caller during an earlier await
, we won't return control back to the caller at later await
s, but we'll be returning it to "something" that isn't our code.
edited yesterday
answered yesterday
Damien_The_UnbelieverDamien_The_Unbeliever
193k17246333
193k17246333
add a comment |
add a comment |
If a method returns a
Task
orTask<T>
(with exception to void in case of event handler) then it can be awaited and hence it can be asynchronous.async
keyword is only an indication that it mayawait
somewhere for another awaitable. Based on the control flow,async
may return without actually awaiting anything.
Asynchronous programming is not a new thing, it has existed in many forms like callbacks, Invokes etc.Examples you have provided are not using async await pattern properly. Microsoft has provided naming convention (Async Suffix) and
Task<T>
,Task
as types for async programming. So if you see some method returningTask<T>
orTask
and Method name has suffix "Async" then you can consider it asynchronous. Although suffix thing is not required by compiler, it helps in differentiating it from its synchronous counterpart. (Read
vsReadAsync
)They are bad examples, those action should be marked as async and all the Async methods should be awaited for result. There can be an exception in some console program where main can't be async.
Please read Stephen Cleary blog on async await
add a comment |
If a method returns a
Task
orTask<T>
(with exception to void in case of event handler) then it can be awaited and hence it can be asynchronous.async
keyword is only an indication that it mayawait
somewhere for another awaitable. Based on the control flow,async
may return without actually awaiting anything.
Asynchronous programming is not a new thing, it has existed in many forms like callbacks, Invokes etc.Examples you have provided are not using async await pattern properly. Microsoft has provided naming convention (Async Suffix) and
Task<T>
,Task
as types for async programming. So if you see some method returningTask<T>
orTask
and Method name has suffix "Async" then you can consider it asynchronous. Although suffix thing is not required by compiler, it helps in differentiating it from its synchronous counterpart. (Read
vsReadAsync
)They are bad examples, those action should be marked as async and all the Async methods should be awaited for result. There can be an exception in some console program where main can't be async.
Please read Stephen Cleary blog on async await
add a comment |
If a method returns a
Task
orTask<T>
(with exception to void in case of event handler) then it can be awaited and hence it can be asynchronous.async
keyword is only an indication that it mayawait
somewhere for another awaitable. Based on the control flow,async
may return without actually awaiting anything.
Asynchronous programming is not a new thing, it has existed in many forms like callbacks, Invokes etc.Examples you have provided are not using async await pattern properly. Microsoft has provided naming convention (Async Suffix) and
Task<T>
,Task
as types for async programming. So if you see some method returningTask<T>
orTask
and Method name has suffix "Async" then you can consider it asynchronous. Although suffix thing is not required by compiler, it helps in differentiating it from its synchronous counterpart. (Read
vsReadAsync
)They are bad examples, those action should be marked as async and all the Async methods should be awaited for result. There can be an exception in some console program where main can't be async.
Please read Stephen Cleary blog on async await
If a method returns a
Task
orTask<T>
(with exception to void in case of event handler) then it can be awaited and hence it can be asynchronous.async
keyword is only an indication that it mayawait
somewhere for another awaitable. Based on the control flow,async
may return without actually awaiting anything.
Asynchronous programming is not a new thing, it has existed in many forms like callbacks, Invokes etc.Examples you have provided are not using async await pattern properly. Microsoft has provided naming convention (Async Suffix) and
Task<T>
,Task
as types for async programming. So if you see some method returningTask<T>
orTask
and Method name has suffix "Async" then you can consider it asynchronous. Although suffix thing is not required by compiler, it helps in differentiating it from its synchronous counterpart. (Read
vsReadAsync
)They are bad examples, those action should be marked as async and all the Async methods should be awaited for result. There can be an exception in some console program where main can't be async.
Please read Stephen Cleary blog on async await
edited yesterday
Damien_The_Unbeliever
193k17246333
193k17246333
answered yesterday
Sarvesh MishraSarvesh Mishra
1,662924
1,662924
add a comment |
add a comment |
An asynchronous method in C# can return void
, Task
or Task<T>
, where void
should be avoided in general because it cannot be awaited.
As a convention asynchronous methods should be called DoSomethingAsync()
The async
keyword, however, is an implementation detail and does not belong to the API. This keyword is only required if you use an await
in the method body. But that need not be the case. You could simply delegate to another asynchronous method, without the need to mark the method as async
and using an await
.
So 'true' asynchronous methods should be recognizable by the Async
suffix of the method name, however, you can't be sure the implementor actually uses naturally asynchronous operations or even runs synchronously some parts or the whole method.
In the example he made the method synchronously by putting .Result
at the end of GetStringAsync
by the Async prefix of the method name
- unless the author did not bother to follow that convention, or unless it is a legacy method the name for which was selected before introduction ofawait
(yes, they exist in .NET).
– GSerg
yesterday
2
Postfix , that is. Prefix would be "AsyncDoSomething".
– Fildor
yesterday
3
Suffix, since we're nit-picking
– Matthew Evans
yesterday
add a comment |
An asynchronous method in C# can return void
, Task
or Task<T>
, where void
should be avoided in general because it cannot be awaited.
As a convention asynchronous methods should be called DoSomethingAsync()
The async
keyword, however, is an implementation detail and does not belong to the API. This keyword is only required if you use an await
in the method body. But that need not be the case. You could simply delegate to another asynchronous method, without the need to mark the method as async
and using an await
.
So 'true' asynchronous methods should be recognizable by the Async
suffix of the method name, however, you can't be sure the implementor actually uses naturally asynchronous operations or even runs synchronously some parts or the whole method.
In the example he made the method synchronously by putting .Result
at the end of GetStringAsync
by the Async prefix of the method name
- unless the author did not bother to follow that convention, or unless it is a legacy method the name for which was selected before introduction ofawait
(yes, they exist in .NET).
– GSerg
yesterday
2
Postfix , that is. Prefix would be "AsyncDoSomething".
– Fildor
yesterday
3
Suffix, since we're nit-picking
– Matthew Evans
yesterday
add a comment |
An asynchronous method in C# can return void
, Task
or Task<T>
, where void
should be avoided in general because it cannot be awaited.
As a convention asynchronous methods should be called DoSomethingAsync()
The async
keyword, however, is an implementation detail and does not belong to the API. This keyword is only required if you use an await
in the method body. But that need not be the case. You could simply delegate to another asynchronous method, without the need to mark the method as async
and using an await
.
So 'true' asynchronous methods should be recognizable by the Async
suffix of the method name, however, you can't be sure the implementor actually uses naturally asynchronous operations or even runs synchronously some parts or the whole method.
In the example he made the method synchronously by putting .Result
at the end of GetStringAsync
An asynchronous method in C# can return void
, Task
or Task<T>
, where void
should be avoided in general because it cannot be awaited.
As a convention asynchronous methods should be called DoSomethingAsync()
The async
keyword, however, is an implementation detail and does not belong to the API. This keyword is only required if you use an await
in the method body. But that need not be the case. You could simply delegate to another asynchronous method, without the need to mark the method as async
and using an await
.
So 'true' asynchronous methods should be recognizable by the Async
suffix of the method name, however, you can't be sure the implementor actually uses naturally asynchronous operations or even runs synchronously some parts or the whole method.
In the example he made the method synchronously by putting .Result
at the end of GetStringAsync
edited yesterday
answered yesterday
CreepinCreepin
137113
137113
by the Async prefix of the method name
- unless the author did not bother to follow that convention, or unless it is a legacy method the name for which was selected before introduction ofawait
(yes, they exist in .NET).
– GSerg
yesterday
2
Postfix , that is. Prefix would be "AsyncDoSomething".
– Fildor
yesterday
3
Suffix, since we're nit-picking
– Matthew Evans
yesterday
add a comment |
by the Async prefix of the method name
- unless the author did not bother to follow that convention, or unless it is a legacy method the name for which was selected before introduction ofawait
(yes, they exist in .NET).
– GSerg
yesterday
2
Postfix , that is. Prefix would be "AsyncDoSomething".
– Fildor
yesterday
3
Suffix, since we're nit-picking
– Matthew Evans
yesterday
by the Async prefix of the method name
- unless the author did not bother to follow that convention, or unless it is a legacy method the name for which was selected before introduction of await
(yes, they exist in .NET).– GSerg
yesterday
by the Async prefix of the method name
- unless the author did not bother to follow that convention, or unless it is a legacy method the name for which was selected before introduction of await
(yes, they exist in .NET).– GSerg
yesterday
2
2
Postfix , that is. Prefix would be "AsyncDoSomething".
– Fildor
yesterday
Postfix , that is. Prefix would be "AsyncDoSomething".
– Fildor
yesterday
3
3
Suffix, since we're nit-picking
– Matthew Evans
yesterday
Suffix, since we're nit-picking
– Matthew Evans
yesterday
add a comment |
vpDev is a new contributor. Be nice, and check out our Code of Conduct.
vpDev is a new contributor. Be nice, and check out our Code of Conduct.
vpDev is a new contributor. Be nice, and check out our Code of Conduct.
vpDev is a new contributor. Be nice, and check out our Code of Conduct.
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%2f54251841%2fin-net-are-async-methods-exclusively-those-with-the-async-keyword%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
"For simplicity's sake" he implemented it wrong, in more than 1 aspect. It's a bad example (first snippet "GetReleases").
– Fildor
yesterday
1
are asynchronous methods implemented exclusively using the async keyword?
- no, the keywordasync
means "I may useawait
inside this method". In order to be awaitable, a method must returnTask
, whether or not it itself is marked asasync
.– GSerg
yesterday
1
To add to GSerg: Neither of which will tell you 100% that the function will be executed asynchronously, though.
– Fildor
yesterday
2
I would suggest blog.stephencleary.com/2012/02/async-and-await.html as a starting point, and then follow links from there (specifically, don't miss blog.stephencleary.com/2012/07/dont-block-on-async-code.html).
– GSerg
yesterday
async essentially is a keyword that implies that you want to use asynchronous programming. (aka, it's a keyword that refers to a pattern -ish)
– Dennis Vanhout
yesterday