简体   繁体   English

为什么C#中的异步调用需要声明,如果它们所在的方法已经使用'async'关键字声明?

[英]Why do asynchronous calls in C# need to be declared as such if the method they reside in is declared with the 'async' keyword already?

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. 现在,有99%的可能性,我发现的这个“挑剔”完全是由于我自己的无知 - 我是一个初级网络开发人员,他只偶尔接触过C#几个月,所以我提前道歉我的问题很可能是愚蠢的。 Most of my experience is with PHP and JS. 我的大部分经验都是使用PHP和JS。

If I have a method declared with the async keyword as such: 如果我有一个使用async关键字声明的方法:

    public async Task<ActionResult> Create(MyObject myObject)
    {
    }

Why do I also have to specify that LINQ statements be asynchronous explicitly like so: 为什么我还必须明确指定LINQ语句是异步的,如下所示:

    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? 难道C#编译器不能聪明地弄清楚因为该方法是异步的,我想在方法中执行的LINQ语句也应该是异步的吗?

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. 我想我真正MaxAsync FirstOrDefaultAsync的是现在大多数LINQ方法( SaveChangesAsyncMaxAsyncFirstOrDefaultAsync )的异步双胞胎,每次我想执行这样的调用时都必须使用await关键字。 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? 如果仍然需要对调用的同步性进行精细控制,为什么C#开发人员不能简单地允许我可以附加的.Await() .Async()Sync()方法?

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? 难道C#编译器不能聪明地弄清楚因为该方法是异步的,我想在方法中执行的LINQ语句也应该是异步的吗?

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#. 我想一种语言可能会这样做,但它需要一个与C#使用的模型不同的根本不同的模型。 Also, I'm not sure it would be a good idea; 另外,我不确定这是个好主意; it could be pretty confusing. 这可能会令人困惑。 Better to make things explicit IMO. 最好把事情做成明确的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. 我想我的真正优势在于现在大多数LINQ方法都存在异步双胞胎(SaveChangesAsync,MaxAsync,FirstOrDefaultAsync),每次我想执行此类调用时都必须使用await关键字。 It seems excessively verbose and unnecessary. 这似乎过于冗长和不必要。

Using await or not doesn't have the same meaning. 使用await与否具有相同的含义。 If you don't use await , you just retrieve the task, which can be useful in some scenarios (eg if you want to parallelize tasks. For instance, consider the following: 如果不使用await ,则只需检索任务,这在某些情况下很有用(例如,如果要并行化任务。例如,请考虑以下事项:

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. 这就是为什么await不能隐含,因为它改变了代码的行为。

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? 如果仍然需要对调用的同步性进行精细控制,为什么C#开发人员不能简单地允许我可以附加的.Await()或.Async()方法?

How would a .Await() method be better than a keyword? .Await()方法如何比关键字更好? Anyway, it wouldn't work. 无论如何,它不会起作用。 The use of the await keyword transforms the body of the method into a state machine; 使用await关键字将方法体转换为状态机; a method call can't do that. 方法调用不能这样做。

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. await完全改变生成方法的代码的方式 - 状态机与线性代码 - 所以你不能用任何自定义.Await()方法神奇地实现它,因为方法调用被编译成线性代码。

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. C#通常选择显式方法与神奇猜测意图 - 所以虽然有些情况下编译器可能猜测需要await调用但它没有。

Note that with var it frequently impossible to make a guess either: 请注意,使用var ,通常无法进行猜测:

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 . displayId可以是Task或者如果编译器允许猜测丢失await它可能是int

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么在静态方法中使用C#枚举类型时无需将其声明为静态? - Why do C# enum types not need to be declared static when used in a static method? C#中的异步方法不是异步的吗? - async method in C# not asynchronous? 在 C# 中,如果方法中的任何异步操作使整个方法异步,为什么我需要在方法中使用多个 await 语句? - In C#, if any asynchronous operation in a method makes an entire method async, why would I need more than one await statement in the method? C#发现隐式类型使用var关键字声明的变量 - C# Discover Implicit Type of variable declared with the var keyword 在Base类中声明的C#接口方法不需要在Derived类中再次实现 - C# interface method declared in Base class need not be again implemented in Derived class 使用在C#中声明的虚拟异步任务并在F#中覆盖它 - Use a virtual async Task declared in C# and override it in F# 如何初始化已经在C#中声明的数组? - How to initialize an array which has already declared in C#? C#获取正确的IntPtr指向已经声明的变量 - C# getting correct IntPtr pointing to already declared variable 在C#/ VB中,如何确定方法是正常声明还是扩展方法? - In C#/VB, how do YOU determine whether a method is declared normally or as an extension method? 如果在另一种方法中声明变量,我如何在一种方法中使用它? C# - How Do I Use A Variable In One Method If It Was Declared In A Different Method? C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM