2015-05-26 22 views
1

我得到的代碼非常類似於此(我簡化了一些代碼來展示我試圖找出行爲的本質)。爲什麼我需要使此方法異步?

public async System.Threading.Tasks.Task<bool> IsNumberOdd(int numToTest) 
{ 
    if (numToTest % 2 == 0) 
    { 
     return false; 
    } 
    else 
    { 
     return true; 
    } 
} 

如果我離開關async關鍵字,我得到一個有關無法投下boolTask<bool>投訴。我假設這裏涉及到一些語法糖。看着IL(我對IL不是很熟悉),好像async關鍵字導致任務運行,然後返回值是任務的結果。我是否正確理解這一點?順便說一下,如果這是一個騙局,或者如果有一些博客文章討論這個,請隨時指向我並關閉它。我並不是想填補我的代表。我試圖瞭解這段代碼發生了什麼。

編輯:


對於所有那些誰被問「爲什麼是這個方法異步?」 - 因爲我想建立一個小而簡單的代碼示例演示了問題。我還應該添加一個調用代碼的例子,但我試圖儘可能保持代碼的小而簡單。

+1

我認爲Jon Skeet的回答完全符合你的問題。 – slugster

+2

如果沒有任何異步要做,但由於簽名的原因你需要返回一個'Task ',那麼你可能需要'Task.FromResult (T值)',即'return Task.FromResult(true);' –

+0

謝謝@ slugster - 正是我想知道的。我的谷歌搜索技巧失敗了:) –

回答

4

我假設這裏還涉及到

不正是「語法糖」的一些語法糖。由於該方法被標記爲async,編譯器正在生成狀態機。這就是爲什麼您可以返回Task<bool>而不明確創建返回值的Task

如果我離開過async關鍵字,我得到一個有關不 能夠施展一個bool到Task<bool>投訴。

async修飾符是觸發編譯器創建狀態機的原因。如果您將其刪除,則需要自行創建Task。如果由於任何原因你想創建一個Task<T>但你實際上同步運行,Task.FromResult是你的朋友。

我看不出爲什麼這種方法被標記爲async

+1

我同意這種方法不需要是異步的。我試圖簡化我正在使用的代碼。 –

+0

@OnorioCatenacci您是否收到您的問題的答案?我不太確定你在問什麼。 –

+0

Re。段落#2:沒有任何'await'的'async'函數將會被編譯,但是會有警告。 'async'自動將結果包裝到'Task '中。 – Richard

0

這不是關於異步。它關於任務。

你返回一個布爾和你的函數的返回值是任務

 public Task<bool> DoSomething() 
    { 
     return false; 
    } 

無法編譯。 如果你沒有做任何事情異步,你不應該返回一個任務。

如果你需要異步運行某些東西,這裏有一些選項,我希望能夠使async/await更清晰。

public class Sample 
{ 
    public async void RunSample() 
    { 
     // return a task. later obtain a result if some fashion 
     Task<bool> task = DoSomethingAsync(); 
     bool res1 = task.Result; 

     // await a task which is created for you by re-wrapping the result. 
     bool res2 = await AwaitSomethingAsync(); 

     // await a task which is created for you by rewrapping the result due to await. 
     bool res3 = await DoSomethingAsync2(); 

     // await a task. 
     bool res4 = await DoSomethingAsync();  
    } 


    public async Task<bool> DoSomethingAsync2() 
    { 
     return false; 
    } 

    public Task<bool> DoSomethingAsync() 
    { 
     return Task<bool>.Run(() => { return false; }); 
    } 

    public async Task<bool> AwaitSomethingAsync() 
    { 
     bool res = await Task<bool>.Run(() => { return false; }); 
     return res; // re-wraps it in a Task 
    } 

} 
+1

這是不正確的。您提供的代碼片段不會編譯。 'async'是觸發編譯器生成狀態機的原因。 –

+0

這個OP是說當'async'被添加並且想知道爲什麼時它會編譯。 OP還聲明,這是一個簡化的代碼來演示這個問題,所以這可能就是爲什麼沒有任何內在的異步關係。 – juharr

+0

如果您將'async'添加到該代碼中,它將會編譯:但是如果沒有'await',將會同步運行。 – Richard

2

它好像async關鍵字是導致任務運行,然後返回值是任務

正確的結果。

這種方法沒有什麼能從async中受益。但是:

如果我離開過async關鍵字,我得到一個有關無法投下boolTask<bool>

將在調用者發生投訴。在沒有看到代碼的情況下,人們通常只能評論您可以:

  • 更改來電者並不認爲它獲得了可等候的回報。
  • 更改函數返回bool,但在呼叫者使用Task.FromResult(IsNumberOdd(value))
+1

簡化的演示代碼來隔離我想知道的行爲。是的,這是人爲的,而不是我爲生產系統寫的東西。 –

+0

@OnorioCatenacci沒有這個調用者,它是不可能具體的:async是調用者和被調用者之間合同的一部分:他們一起工作。 – Richard

相關問題