簡體   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?

現在,有99%的可能性,我發現的這個“挑剔”完全是由於我自己的無知 - 我是一個初級網絡開發人員,他只偶爾接觸過C#幾個月,所以我提前道歉我的問題很可能是愚蠢的。 我的大部分經驗都是使用PHP和JS。

如果我有一個使用async關鍵字聲明的方法:

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

為什么我還必須明確指定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);
    }

難道C#編譯器不能聰明地弄清楚因為該方法是異步的,我想在方法中執行的LINQ語句也應該是異步的嗎?

我想我真正MaxAsync FirstOrDefaultAsync的是現在大多數LINQ方法( SaveChangesAsyncMaxAsyncFirstOrDefaultAsync )的異步雙胞胎,每次我想執行這樣的調用時都必須使用await關鍵字。 這似乎過於冗長和不必要。

如果仍然需要對調用的同步性進行精細控制,為什么C#開發人員不能簡單地允許我可以附加的.Await() .Async()Sync()方法?

難道C#編譯器不能聰明地弄清楚因為該方法是異步的,我想在方法中執行的LINQ語句也應該是異步的嗎?

如果要在異步方法中進行同步調用,該怎么辦?

您是否希望同一方法同步或異步,具體取決於您是否使用異步方法? 我想一種語言可能會這樣做,但它需要一個與C#使用的模型不同的根本不同的模型。 另外,我不確定這是個好主意; 這可能會令人困惑。 最好把事情做成明確的IMO。

我想我的真正優勢在於現在大多數LINQ方法都存在異步雙胞胎(SaveChangesAsync,MaxAsync,FirstOrDefaultAsync),每次我想執行此類調用時都必須使用await關鍵字。 這似乎過於冗長和不必要。

使用await與否具有相同的含義。 如果不使用await ,則只需檢索任務,這在某些情況下很有用(例如,如果要並行化任務。例如,請考慮以下事項:

Task t1 = SomeAsyncOperation();
Task t2 = SomeOtherAsyncOperation();
await Task.WhenAll(t1, t2);

在上面的代碼中,操作並行運行。 現在,如果您在每次通話時使用等待:

await SomeAsyncOperation();
await SomeOtherAsyncOperation();

這些操作現在是順序的。

開發人員需要控制這種事情。 這就是為什么await不能隱含,因為它改變了代碼的行為。

如果仍然需要對調用的同步性進行精細控制,為什么C#開發人員不能簡單地允許我可以附加的.Await()或.Async()方法?

.Await()方法如何比關鍵字更好? 無論如何,它不會起作用。 使用await關鍵字將方法體轉換為狀態機; 方法調用不能這樣做。

await完全改變生成方法的代碼的方式 - 狀態機與線性代碼 - 所以你不能用任何自定義.Await()方法神奇地實現它,因為方法調用被編譯成線性代碼。

C#通常選擇顯式方法與神奇猜測意圖 - 所以雖然有些情況下編譯器可能猜測需要await調用但它沒有。

請注意,使用var ,通常無法進行猜測:

var displayId = db.MyObjects.MaxAsync(m => m.DisplayId);

displayId可以是Task或者如果編譯器允許猜測丟失await它可能是int

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM