Why should asynchronous calls in C # be declared as such if the method in which they reside is declared with the keyword "async" already?

advertisements

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?


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.