Why is auto generated controller Get() method synchronous?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
When creating basic ASP.NET Core 2.1 MVC API web application using Entity, you can generate controller automatically after selecting model and dbContext (RMB -> Add -> Controller... -> API Controller with actions, using Entity Framework).
I wonder why all the methods generated are asynchronous, except for the basic Get() which returns all the table? Is it an error? It's a database call, therefore I'd expect it to be asynchronous. Is there no real benefit of using asynchronous call in this case? If yes, why?
// GET: api/User
[HttpGet]
public IEnumerable<User> GetUsers()
{
return _context.Users;
}
c# .net asp.net-mvc asp.net-core .net-core
add a comment |
When creating basic ASP.NET Core 2.1 MVC API web application using Entity, you can generate controller automatically after selecting model and dbContext (RMB -> Add -> Controller... -> API Controller with actions, using Entity Framework).
I wonder why all the methods generated are asynchronous, except for the basic Get() which returns all the table? Is it an error? It's a database call, therefore I'd expect it to be asynchronous. Is there no real benefit of using asynchronous call in this case? If yes, why?
// GET: api/User
[HttpGet]
public IEnumerable<User> GetUsers()
{
return _context.Users;
}
c# .net asp.net-mvc asp.net-core .net-core
That's just some code based on a default template. You have to wrtite your own code to do what you want. Stickingasync
in the signature won't make the method run asynchronously either.async
is just syntactic sugar that allows usingawait
to await already asynchronous operations, likeToListAsync()
.
– Panagiotis Kanavos
Jan 3 at 14:03
add a comment |
When creating basic ASP.NET Core 2.1 MVC API web application using Entity, you can generate controller automatically after selecting model and dbContext (RMB -> Add -> Controller... -> API Controller with actions, using Entity Framework).
I wonder why all the methods generated are asynchronous, except for the basic Get() which returns all the table? Is it an error? It's a database call, therefore I'd expect it to be asynchronous. Is there no real benefit of using asynchronous call in this case? If yes, why?
// GET: api/User
[HttpGet]
public IEnumerable<User> GetUsers()
{
return _context.Users;
}
c# .net asp.net-mvc asp.net-core .net-core
When creating basic ASP.NET Core 2.1 MVC API web application using Entity, you can generate controller automatically after selecting model and dbContext (RMB -> Add -> Controller... -> API Controller with actions, using Entity Framework).
I wonder why all the methods generated are asynchronous, except for the basic Get() which returns all the table? Is it an error? It's a database call, therefore I'd expect it to be asynchronous. Is there no real benefit of using asynchronous call in this case? If yes, why?
// GET: api/User
[HttpGet]
public IEnumerable<User> GetUsers()
{
return _context.Users;
}
c# .net asp.net-mvc asp.net-core .net-core
c# .net asp.net-mvc asp.net-core .net-core
asked Jan 3 at 13:58
PeacePeace
238
238
That's just some code based on a default template. You have to wrtite your own code to do what you want. Stickingasync
in the signature won't make the method run asynchronously either.async
is just syntactic sugar that allows usingawait
to await already asynchronous operations, likeToListAsync()
.
– Panagiotis Kanavos
Jan 3 at 14:03
add a comment |
That's just some code based on a default template. You have to wrtite your own code to do what you want. Stickingasync
in the signature won't make the method run asynchronously either.async
is just syntactic sugar that allows usingawait
to await already asynchronous operations, likeToListAsync()
.
– Panagiotis Kanavos
Jan 3 at 14:03
That's just some code based on a default template. You have to wrtite your own code to do what you want. Sticking
async
in the signature won't make the method run asynchronously either. async
is just syntactic sugar that allows using await
to await already asynchronous operations, like ToListAsync()
.– Panagiotis Kanavos
Jan 3 at 14:03
That's just some code based on a default template. You have to wrtite your own code to do what you want. Sticking
async
in the signature won't make the method run asynchronously either. async
is just syntactic sugar that allows using await
to await already asynchronous operations, like ToListAsync()
.– Panagiotis Kanavos
Jan 3 at 14:03
add a comment |
2 Answers
2
active
oldest
votes
return _context.Users
simply returns an object of type DbSet<Users>
. It doesn't iterate over it or do any work it's just passing an object that allows you access to database data.
DbSet<T>
is also an IQueryable<T>
, which means the database isn't called until you call some sort of executing function like .ToList()
or .Single(x=>x.Id == idToLookFor)
If you were to iterate over it asynchronously then you would have an async Get() method, ex;
return await _context.Users.ToListAsync()
Update
I realized that actually didn't answer your question,
It's very unlikely that you would ever want to return your entire table. (SELECT * FROM [Users]) So what the Get()
method here is an anti-pattern (in my opinion**) known as 'exposing an IQueryable'
So in your controller you can do something like
_context.Get().Where(user=>user.FirstName == 'Steve').ToList()
or you could make it async as you figure you should be doing on a database call
await _context.Get().Where(user=>user.FirstName == 'Steve').ToListAsync()
So, is the template generated Get()
an error? No, but I have an opinion that you shouldn't be exposing an IQueryable as a public method, so I disagree with it.
IQueryable<T>
var query = _context.Users; //SQL: * FROM [Users]
query = query.Where(x=>x.Name == "Steve");
//SQL: * FROM [Users] WHERE Name = 'Steve'
query = query.Where(x=>x.wearsHats == true);
//SQL: * FROM [Users] WHERE Name = 'Steve' AND WearsHats = true
query = query.Select(x=>x.Name);
//SQL: Name FROM [Users] WHERE Name = 'Steve' AND WearsHats = true
var result = query.ToList()
//SQL: SELECT Name FROM [Users] WHERE Name = 'Steve' AND WearsHats = true
So is_context.Users
cached? What does.ToList()
change exactly? It's still asking for a records in the database, and returning same data (users), which you have to get from the database.
– Peace
Jan 3 at 15:11
I'm not an EF expert, there's a lot more that goes on under the hood than I care to learn about but the gist is DbSet<Users> is empty until you ask for something. When you ask for something, it's translated into an SQL query, which fetches your something from the database, and hands you your something in the type you requested.
– Adam Vincent
Jan 3 at 15:17
If I understand what you've said correctly then exposing bareDbSet<Users>
shouldn't give you any result (you haven't asked for anything), but it works correctly - it provides users table data from the database. How is that so?
– Peace
Jan 3 at 15:21
idk, magic? lol
– Adam Vincent
Jan 3 at 15:23
1
@Peace the MVC infrastructure will iterate over the collection you returned from the controller when writing the response to the client. So the query execution is delayed until then. IMO it's a better practice to execute the query yourself by usingToList()
or more preferablyawait _context.Users.ToListAsync()
.
– Henk Mollema
Jan 3 at 15:43
|
show 1 more comment
Yes, this is very inconsistent with all the other async actions. I don't think there is any specific reason for this. I think that Microsoft just forgot to update this part of the template. I would expect the following to be generated:
// GET: api/User
[HttpGet]
public async Task<ActionResult<IEnumerable<User>>> GetUsers()
{
return await _context.Users.ToListAsync();
}
Even a one liner action can still benefit from being async - the IIS thread will not be blocked during the database query. You can read more about that in other questions on SO, for example here: When should I use Async Controllers in ASP.NET MVC?
EDIT: You can find the template sources on github. You can see in lines 38-42 that in the latest version this action is updated and will be generated in an async way exactly as I've written above.
I don't think the template is outdated. All the other methods are written with modern patterns and seems up-to-date. Whole template was updated not so long ago. I think there must be some reason why Microsoft made it this way.
– Peace
Jan 3 at 15:29
@Peace I guess "outdated template" is not exactly the right expression. What I meant is I think that Microsoft forgot to update the template part for this specific action. The fact that all the other actions are written in a modern way makes this one lonely synchronous action look even more out of place.
– LambdaCruiser
Jan 3 at 16:11
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%2f54023761%2fwhy-is-auto-generated-controller-get-method-synchronous%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
return _context.Users
simply returns an object of type DbSet<Users>
. It doesn't iterate over it or do any work it's just passing an object that allows you access to database data.
DbSet<T>
is also an IQueryable<T>
, which means the database isn't called until you call some sort of executing function like .ToList()
or .Single(x=>x.Id == idToLookFor)
If you were to iterate over it asynchronously then you would have an async Get() method, ex;
return await _context.Users.ToListAsync()
Update
I realized that actually didn't answer your question,
It's very unlikely that you would ever want to return your entire table. (SELECT * FROM [Users]) So what the Get()
method here is an anti-pattern (in my opinion**) known as 'exposing an IQueryable'
So in your controller you can do something like
_context.Get().Where(user=>user.FirstName == 'Steve').ToList()
or you could make it async as you figure you should be doing on a database call
await _context.Get().Where(user=>user.FirstName == 'Steve').ToListAsync()
So, is the template generated Get()
an error? No, but I have an opinion that you shouldn't be exposing an IQueryable as a public method, so I disagree with it.
IQueryable<T>
var query = _context.Users; //SQL: * FROM [Users]
query = query.Where(x=>x.Name == "Steve");
//SQL: * FROM [Users] WHERE Name = 'Steve'
query = query.Where(x=>x.wearsHats == true);
//SQL: * FROM [Users] WHERE Name = 'Steve' AND WearsHats = true
query = query.Select(x=>x.Name);
//SQL: Name FROM [Users] WHERE Name = 'Steve' AND WearsHats = true
var result = query.ToList()
//SQL: SELECT Name FROM [Users] WHERE Name = 'Steve' AND WearsHats = true
So is_context.Users
cached? What does.ToList()
change exactly? It's still asking for a records in the database, and returning same data (users), which you have to get from the database.
– Peace
Jan 3 at 15:11
I'm not an EF expert, there's a lot more that goes on under the hood than I care to learn about but the gist is DbSet<Users> is empty until you ask for something. When you ask for something, it's translated into an SQL query, which fetches your something from the database, and hands you your something in the type you requested.
– Adam Vincent
Jan 3 at 15:17
If I understand what you've said correctly then exposing bareDbSet<Users>
shouldn't give you any result (you haven't asked for anything), but it works correctly - it provides users table data from the database. How is that so?
– Peace
Jan 3 at 15:21
idk, magic? lol
– Adam Vincent
Jan 3 at 15:23
1
@Peace the MVC infrastructure will iterate over the collection you returned from the controller when writing the response to the client. So the query execution is delayed until then. IMO it's a better practice to execute the query yourself by usingToList()
or more preferablyawait _context.Users.ToListAsync()
.
– Henk Mollema
Jan 3 at 15:43
|
show 1 more comment
return _context.Users
simply returns an object of type DbSet<Users>
. It doesn't iterate over it or do any work it's just passing an object that allows you access to database data.
DbSet<T>
is also an IQueryable<T>
, which means the database isn't called until you call some sort of executing function like .ToList()
or .Single(x=>x.Id == idToLookFor)
If you were to iterate over it asynchronously then you would have an async Get() method, ex;
return await _context.Users.ToListAsync()
Update
I realized that actually didn't answer your question,
It's very unlikely that you would ever want to return your entire table. (SELECT * FROM [Users]) So what the Get()
method here is an anti-pattern (in my opinion**) known as 'exposing an IQueryable'
So in your controller you can do something like
_context.Get().Where(user=>user.FirstName == 'Steve').ToList()
or you could make it async as you figure you should be doing on a database call
await _context.Get().Where(user=>user.FirstName == 'Steve').ToListAsync()
So, is the template generated Get()
an error? No, but I have an opinion that you shouldn't be exposing an IQueryable as a public method, so I disagree with it.
IQueryable<T>
var query = _context.Users; //SQL: * FROM [Users]
query = query.Where(x=>x.Name == "Steve");
//SQL: * FROM [Users] WHERE Name = 'Steve'
query = query.Where(x=>x.wearsHats == true);
//SQL: * FROM [Users] WHERE Name = 'Steve' AND WearsHats = true
query = query.Select(x=>x.Name);
//SQL: Name FROM [Users] WHERE Name = 'Steve' AND WearsHats = true
var result = query.ToList()
//SQL: SELECT Name FROM [Users] WHERE Name = 'Steve' AND WearsHats = true
So is_context.Users
cached? What does.ToList()
change exactly? It's still asking for a records in the database, and returning same data (users), which you have to get from the database.
– Peace
Jan 3 at 15:11
I'm not an EF expert, there's a lot more that goes on under the hood than I care to learn about but the gist is DbSet<Users> is empty until you ask for something. When you ask for something, it's translated into an SQL query, which fetches your something from the database, and hands you your something in the type you requested.
– Adam Vincent
Jan 3 at 15:17
If I understand what you've said correctly then exposing bareDbSet<Users>
shouldn't give you any result (you haven't asked for anything), but it works correctly - it provides users table data from the database. How is that so?
– Peace
Jan 3 at 15:21
idk, magic? lol
– Adam Vincent
Jan 3 at 15:23
1
@Peace the MVC infrastructure will iterate over the collection you returned from the controller when writing the response to the client. So the query execution is delayed until then. IMO it's a better practice to execute the query yourself by usingToList()
or more preferablyawait _context.Users.ToListAsync()
.
– Henk Mollema
Jan 3 at 15:43
|
show 1 more comment
return _context.Users
simply returns an object of type DbSet<Users>
. It doesn't iterate over it or do any work it's just passing an object that allows you access to database data.
DbSet<T>
is also an IQueryable<T>
, which means the database isn't called until you call some sort of executing function like .ToList()
or .Single(x=>x.Id == idToLookFor)
If you were to iterate over it asynchronously then you would have an async Get() method, ex;
return await _context.Users.ToListAsync()
Update
I realized that actually didn't answer your question,
It's very unlikely that you would ever want to return your entire table. (SELECT * FROM [Users]) So what the Get()
method here is an anti-pattern (in my opinion**) known as 'exposing an IQueryable'
So in your controller you can do something like
_context.Get().Where(user=>user.FirstName == 'Steve').ToList()
or you could make it async as you figure you should be doing on a database call
await _context.Get().Where(user=>user.FirstName == 'Steve').ToListAsync()
So, is the template generated Get()
an error? No, but I have an opinion that you shouldn't be exposing an IQueryable as a public method, so I disagree with it.
IQueryable<T>
var query = _context.Users; //SQL: * FROM [Users]
query = query.Where(x=>x.Name == "Steve");
//SQL: * FROM [Users] WHERE Name = 'Steve'
query = query.Where(x=>x.wearsHats == true);
//SQL: * FROM [Users] WHERE Name = 'Steve' AND WearsHats = true
query = query.Select(x=>x.Name);
//SQL: Name FROM [Users] WHERE Name = 'Steve' AND WearsHats = true
var result = query.ToList()
//SQL: SELECT Name FROM [Users] WHERE Name = 'Steve' AND WearsHats = true
return _context.Users
simply returns an object of type DbSet<Users>
. It doesn't iterate over it or do any work it's just passing an object that allows you access to database data.
DbSet<T>
is also an IQueryable<T>
, which means the database isn't called until you call some sort of executing function like .ToList()
or .Single(x=>x.Id == idToLookFor)
If you were to iterate over it asynchronously then you would have an async Get() method, ex;
return await _context.Users.ToListAsync()
Update
I realized that actually didn't answer your question,
It's very unlikely that you would ever want to return your entire table. (SELECT * FROM [Users]) So what the Get()
method here is an anti-pattern (in my opinion**) known as 'exposing an IQueryable'
So in your controller you can do something like
_context.Get().Where(user=>user.FirstName == 'Steve').ToList()
or you could make it async as you figure you should be doing on a database call
await _context.Get().Where(user=>user.FirstName == 'Steve').ToListAsync()
So, is the template generated Get()
an error? No, but I have an opinion that you shouldn't be exposing an IQueryable as a public method, so I disagree with it.
IQueryable<T>
var query = _context.Users; //SQL: * FROM [Users]
query = query.Where(x=>x.Name == "Steve");
//SQL: * FROM [Users] WHERE Name = 'Steve'
query = query.Where(x=>x.wearsHats == true);
//SQL: * FROM [Users] WHERE Name = 'Steve' AND WearsHats = true
query = query.Select(x=>x.Name);
//SQL: Name FROM [Users] WHERE Name = 'Steve' AND WearsHats = true
var result = query.ToList()
//SQL: SELECT Name FROM [Users] WHERE Name = 'Steve' AND WearsHats = true
edited Jan 3 at 15:36
answered Jan 3 at 14:56
Adam VincentAdam Vincent
1,514528
1,514528
So is_context.Users
cached? What does.ToList()
change exactly? It's still asking for a records in the database, and returning same data (users), which you have to get from the database.
– Peace
Jan 3 at 15:11
I'm not an EF expert, there's a lot more that goes on under the hood than I care to learn about but the gist is DbSet<Users> is empty until you ask for something. When you ask for something, it's translated into an SQL query, which fetches your something from the database, and hands you your something in the type you requested.
– Adam Vincent
Jan 3 at 15:17
If I understand what you've said correctly then exposing bareDbSet<Users>
shouldn't give you any result (you haven't asked for anything), but it works correctly - it provides users table data from the database. How is that so?
– Peace
Jan 3 at 15:21
idk, magic? lol
– Adam Vincent
Jan 3 at 15:23
1
@Peace the MVC infrastructure will iterate over the collection you returned from the controller when writing the response to the client. So the query execution is delayed until then. IMO it's a better practice to execute the query yourself by usingToList()
or more preferablyawait _context.Users.ToListAsync()
.
– Henk Mollema
Jan 3 at 15:43
|
show 1 more comment
So is_context.Users
cached? What does.ToList()
change exactly? It's still asking for a records in the database, and returning same data (users), which you have to get from the database.
– Peace
Jan 3 at 15:11
I'm not an EF expert, there's a lot more that goes on under the hood than I care to learn about but the gist is DbSet<Users> is empty until you ask for something. When you ask for something, it's translated into an SQL query, which fetches your something from the database, and hands you your something in the type you requested.
– Adam Vincent
Jan 3 at 15:17
If I understand what you've said correctly then exposing bareDbSet<Users>
shouldn't give you any result (you haven't asked for anything), but it works correctly - it provides users table data from the database. How is that so?
– Peace
Jan 3 at 15:21
idk, magic? lol
– Adam Vincent
Jan 3 at 15:23
1
@Peace the MVC infrastructure will iterate over the collection you returned from the controller when writing the response to the client. So the query execution is delayed until then. IMO it's a better practice to execute the query yourself by usingToList()
or more preferablyawait _context.Users.ToListAsync()
.
– Henk Mollema
Jan 3 at 15:43
So is
_context.Users
cached? What does .ToList()
change exactly? It's still asking for a records in the database, and returning same data (users), which you have to get from the database.– Peace
Jan 3 at 15:11
So is
_context.Users
cached? What does .ToList()
change exactly? It's still asking for a records in the database, and returning same data (users), which you have to get from the database.– Peace
Jan 3 at 15:11
I'm not an EF expert, there's a lot more that goes on under the hood than I care to learn about but the gist is DbSet<Users> is empty until you ask for something. When you ask for something, it's translated into an SQL query, which fetches your something from the database, and hands you your something in the type you requested.
– Adam Vincent
Jan 3 at 15:17
I'm not an EF expert, there's a lot more that goes on under the hood than I care to learn about but the gist is DbSet<Users> is empty until you ask for something. When you ask for something, it's translated into an SQL query, which fetches your something from the database, and hands you your something in the type you requested.
– Adam Vincent
Jan 3 at 15:17
If I understand what you've said correctly then exposing bare
DbSet<Users>
shouldn't give you any result (you haven't asked for anything), but it works correctly - it provides users table data from the database. How is that so?– Peace
Jan 3 at 15:21
If I understand what you've said correctly then exposing bare
DbSet<Users>
shouldn't give you any result (you haven't asked for anything), but it works correctly - it provides users table data from the database. How is that so?– Peace
Jan 3 at 15:21
idk, magic? lol
– Adam Vincent
Jan 3 at 15:23
idk, magic? lol
– Adam Vincent
Jan 3 at 15:23
1
1
@Peace the MVC infrastructure will iterate over the collection you returned from the controller when writing the response to the client. So the query execution is delayed until then. IMO it's a better practice to execute the query yourself by using
ToList()
or more preferably await _context.Users.ToListAsync()
.– Henk Mollema
Jan 3 at 15:43
@Peace the MVC infrastructure will iterate over the collection you returned from the controller when writing the response to the client. So the query execution is delayed until then. IMO it's a better practice to execute the query yourself by using
ToList()
or more preferably await _context.Users.ToListAsync()
.– Henk Mollema
Jan 3 at 15:43
|
show 1 more comment
Yes, this is very inconsistent with all the other async actions. I don't think there is any specific reason for this. I think that Microsoft just forgot to update this part of the template. I would expect the following to be generated:
// GET: api/User
[HttpGet]
public async Task<ActionResult<IEnumerable<User>>> GetUsers()
{
return await _context.Users.ToListAsync();
}
Even a one liner action can still benefit from being async - the IIS thread will not be blocked during the database query. You can read more about that in other questions on SO, for example here: When should I use Async Controllers in ASP.NET MVC?
EDIT: You can find the template sources on github. You can see in lines 38-42 that in the latest version this action is updated and will be generated in an async way exactly as I've written above.
I don't think the template is outdated. All the other methods are written with modern patterns and seems up-to-date. Whole template was updated not so long ago. I think there must be some reason why Microsoft made it this way.
– Peace
Jan 3 at 15:29
@Peace I guess "outdated template" is not exactly the right expression. What I meant is I think that Microsoft forgot to update the template part for this specific action. The fact that all the other actions are written in a modern way makes this one lonely synchronous action look even more out of place.
– LambdaCruiser
Jan 3 at 16:11
add a comment |
Yes, this is very inconsistent with all the other async actions. I don't think there is any specific reason for this. I think that Microsoft just forgot to update this part of the template. I would expect the following to be generated:
// GET: api/User
[HttpGet]
public async Task<ActionResult<IEnumerable<User>>> GetUsers()
{
return await _context.Users.ToListAsync();
}
Even a one liner action can still benefit from being async - the IIS thread will not be blocked during the database query. You can read more about that in other questions on SO, for example here: When should I use Async Controllers in ASP.NET MVC?
EDIT: You can find the template sources on github. You can see in lines 38-42 that in the latest version this action is updated and will be generated in an async way exactly as I've written above.
I don't think the template is outdated. All the other methods are written with modern patterns and seems up-to-date. Whole template was updated not so long ago. I think there must be some reason why Microsoft made it this way.
– Peace
Jan 3 at 15:29
@Peace I guess "outdated template" is not exactly the right expression. What I meant is I think that Microsoft forgot to update the template part for this specific action. The fact that all the other actions are written in a modern way makes this one lonely synchronous action look even more out of place.
– LambdaCruiser
Jan 3 at 16:11
add a comment |
Yes, this is very inconsistent with all the other async actions. I don't think there is any specific reason for this. I think that Microsoft just forgot to update this part of the template. I would expect the following to be generated:
// GET: api/User
[HttpGet]
public async Task<ActionResult<IEnumerable<User>>> GetUsers()
{
return await _context.Users.ToListAsync();
}
Even a one liner action can still benefit from being async - the IIS thread will not be blocked during the database query. You can read more about that in other questions on SO, for example here: When should I use Async Controllers in ASP.NET MVC?
EDIT: You can find the template sources on github. You can see in lines 38-42 that in the latest version this action is updated and will be generated in an async way exactly as I've written above.
Yes, this is very inconsistent with all the other async actions. I don't think there is any specific reason for this. I think that Microsoft just forgot to update this part of the template. I would expect the following to be generated:
// GET: api/User
[HttpGet]
public async Task<ActionResult<IEnumerable<User>>> GetUsers()
{
return await _context.Users.ToListAsync();
}
Even a one liner action can still benefit from being async - the IIS thread will not be blocked during the database query. You can read more about that in other questions on SO, for example here: When should I use Async Controllers in ASP.NET MVC?
EDIT: You can find the template sources on github. You can see in lines 38-42 that in the latest version this action is updated and will be generated in an async way exactly as I've written above.
edited Jan 3 at 16:39
answered Jan 3 at 14:28
LambdaCruiserLambdaCruiser
463411
463411
I don't think the template is outdated. All the other methods are written with modern patterns and seems up-to-date. Whole template was updated not so long ago. I think there must be some reason why Microsoft made it this way.
– Peace
Jan 3 at 15:29
@Peace I guess "outdated template" is not exactly the right expression. What I meant is I think that Microsoft forgot to update the template part for this specific action. The fact that all the other actions are written in a modern way makes this one lonely synchronous action look even more out of place.
– LambdaCruiser
Jan 3 at 16:11
add a comment |
I don't think the template is outdated. All the other methods are written with modern patterns and seems up-to-date. Whole template was updated not so long ago. I think there must be some reason why Microsoft made it this way.
– Peace
Jan 3 at 15:29
@Peace I guess "outdated template" is not exactly the right expression. What I meant is I think that Microsoft forgot to update the template part for this specific action. The fact that all the other actions are written in a modern way makes this one lonely synchronous action look even more out of place.
– LambdaCruiser
Jan 3 at 16:11
I don't think the template is outdated. All the other methods are written with modern patterns and seems up-to-date. Whole template was updated not so long ago. I think there must be some reason why Microsoft made it this way.
– Peace
Jan 3 at 15:29
I don't think the template is outdated. All the other methods are written with modern patterns and seems up-to-date. Whole template was updated not so long ago. I think there must be some reason why Microsoft made it this way.
– Peace
Jan 3 at 15:29
@Peace I guess "outdated template" is not exactly the right expression. What I meant is I think that Microsoft forgot to update the template part for this specific action. The fact that all the other actions are written in a modern way makes this one lonely synchronous action look even more out of place.
– LambdaCruiser
Jan 3 at 16:11
@Peace I guess "outdated template" is not exactly the right expression. What I meant is I think that Microsoft forgot to update the template part for this specific action. The fact that all the other actions are written in a modern way makes this one lonely synchronous action look even more out of place.
– LambdaCruiser
Jan 3 at 16:11
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%2f54023761%2fwhy-is-auto-generated-controller-get-method-synchronous%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
That's just some code based on a default template. You have to wrtite your own code to do what you want. Sticking
async
in the signature won't make the method run asynchronously either.async
is just syntactic sugar that allows usingawait
to await already asynchronous operations, likeToListAsync()
.– Panagiotis Kanavos
Jan 3 at 14:03