2011-12-14 90 views
32

我最近已經從Objective-C領域轉移回C#,並且C#5中的async/await關鍵字看起來很酷。但我仍然試圖理解正確的語法。傳遞異步委託的方法簽名是什麼?

我想聲明一個將異步委託作爲參數的方法,但是我無法正確調用調用者和被調用者的語法。有人可以提供一個代碼示例,顯示方法聲明,調用以及對委託的調用嗎?

我在想這個聲明會像下面這樣。請注意,此功能不是異步的;即其異步性與代表無關。

void DoSomethingWithCallback(async delegate foo(int)) 
{ 
    ... 
    foo(42); 
    ... 
} 

呼叫會是這樣的:

DoSomethingWithCallback(async (int x) => { this.SomeProperty = await SomeAsync(x); }); 

當然這一切都不中編譯和大多數我見過假設一個具有字段或屬性是這樣的代表,而不是樣品我想使用的匿名代理。

+0

盡我所知,沒有辦法指定內聯代理,就像我在上面的問題中所做的那樣。要使用委託作爲方法參數,委託類型需要在類作用域之外聲明。 – AndrewS 2011-12-15 17:13:34

回答

47

將委託作爲參數的函數必須使用指定的委託類型;與Objective-C不同的是,您不能在函數定義中內聯聲明匿名委託類型。但是,提供了仿製藥動作<>和Func <>,因此您無需自行申報新的類型。在下面的代碼中,我假設代表採用單個int作爲參數。

void DoSomethingWithCallback(Func<int,Task> callbackDelegate) 
{ 
    Task t = callbackDelegate(42); 
} 

如果這個功能不實際上做任何與任務對象返回(如上面所示的代碼),您可以改用Action<int>作爲委託類型。如果使用Action,則仍然可以聲明委託異步(見下文),但隱式返回的Task對象將被忽略。

調用上述函數的lambda語法非常簡單,您在問題中使用的語法是正確的。需要注意的是參數類型不需要在這裏指定,因爲它可以推斷出:

DoSomethingWithCallback(async (intParam) => { this.myint = await Int2IntAsync(intParam); }); 

您還可以通過一種方法或委託變量,如果你願意的話,而不是使用lambda語法:

async Task MyInt2Int(int p) { ... } 
Func<int,Task> myDelegate; 
void OtherMethod() 
{ 
    myDelegate = MyInt2Int; 
    DoSomethingWithCallback(myDelegate); // this ... 
    DoSomethingWithCallback(MyInt2Int); // ... or this. 
} 
5

如果沒有返回類型,則方法簽名的返回類型爲Task;如果有返回類型,則返回Task<T>

Th,如果您可以擁有這樣的異步lambdas,我不是100%確定的。

在消耗任務的方法中,您將「等待」任務或使用Task上的屬性和方法來獲取結果。

+10

是的,我們支持異步lambdas。如果我自己這樣說,那就太漂亮了。 – 2011-12-14 21:04:09