Reputation: 10408
Now, there's a 99% chance that this "nitpick" I have found is entirely due to my own ignorance - I'm a junior web developer who has only been exposed to C# sporadically for a couple of months, so I apologize in advance for the probable stupidity of my question. Most of my experience is with PHP and JS.
If I have a method declared with the async
keyword as such:
public async Task<ActionResult> Create(MyObject myObject)
{
}
Why do I also have to specify that LINQ statements be asynchronous explicitly like so:
public async Task<ActionResult> Create(MyObject myObject)
{
if (ModelState.IsValid)
{
myObject.Id = Guid.NewGuid();
myObject.DisplayId = await db.MyObjects.MaxAsync(m => m.DisplayId) + 1;
db.MyObjects.Add(myObject);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(myObject);
}
Can't the C# compiler be clever enough to figure out that because the method is asynychronous, the LINQ statements I want to execute within the method should be asynchronous too?
I guess my real beef with this is that there's now an asynchronous twin for most LINQ methods (SaveChangesAsync
, MaxAsync
, FirstOrDefaultAsync
), and I have to use the await
keyword every time I want to execute such calls. It seems excessively verbose and unnecessary.
If granular control over the synchronicity of the call was still needed, why didn't the C# developers simply allow for an .Await()
,.Async()
, or Sync()
method that I could append?
Upvotes: 3
Views: 233
Reputation: 292435
Can't the C# compiler be clever enough to figure out that because the method is asynychronous, the LINQ statements I want to execute within the method should be asynchronous too?
What if you want to make a synchronous call in an asynchronous method?
Do you want the same method to be synchronous or asynchronous depending on whether or not you're in an asynchronous method? I guess it would be possible for a language to do that, but it would require a fundamentally different model that is not the one used by C#. Also, I'm not sure it would be a good idea; it could be pretty confusing. Better to make things explicit IMO.
I guess my real beef with this is that there's now an asynchronous twin for most LINQ methods (SaveChangesAsync, MaxAsync, FirstOrDefaultAsync), and I have to use the await keyword every time I want to execute such calls. It seems excessively verbose and unnecessary.
Using await
or not doesn't have the same meaning. If you don't use await
, you just retrieve the task, which can be useful in some scenarios (e.g. if you want to parallelize tasks. For instance, consider the following:
Task t1 = SomeAsyncOperation();
Task t2 = SomeOtherAsyncOperation();
await Task.WhenAll(t1, t2);
In the code above, the operations run in parallel. Now, if you use await on each call:
await SomeAsyncOperation();
await SomeOtherAsyncOperation();
The operations are now sequential.
The developer needs to be in control of this kind of thing. That's why the await
cannot be implicit, because it changes the behavior of the code.
If granular control over the synchronicity of the call was still needed, why didn't the C# developers simply allow for an .Await() or .Async() method that I could append?
How would a .Await()
method be better than a keyword? Anyway, it wouldn't work. The use of the await
keyword transforms the body of the method into a state machine; a method call can't do that.
Upvotes: 5
Reputation: 100547
await
completely changes the way code for the method is generated - state machine vs. linear code - so you can't magically implement it with any custom .Await()
method because method calls compiled into linear code.
C# generally chooses explicit approach vs. magically guess intentions - so while there are cases when compiler may guess need for await
call it does not.
Note that with var
it frequently impossible to make a guess either:
var displayId = db.MyObjects.MaxAsync(m => m.DisplayId);
displayId
could be Task
or if compiler allowed to guess for missing await
it could be int
.
Upvotes: 1