2011-07-17 161 views
2

我習慣於Javascript,我可以簡單地將一個函數作爲參數傳遞,以便稍後用作回調函數。這很好,很容易。C#中的回調函數#

現在我正在編寫一個應用程序在c#中,並希望完成同樣的事情。

基本上,我的應用程序如下所示,需要身份驗證令牌。但是,在getData階段,如果令牌已過期,我需要調用refreshToken()。如何通過refreshToken()傳遞迴調函數,以便getData在刷新令牌時知道要調用什麼?

這裏是什麼,我會在Javascript中做一個圖,但我會去用C#這樣做,或只是路過回調一般?:

getData(callback); 
// Looks like the token is expired, exiting the getData function and refreshing token 
refreshToken(function(){ getData(callback); }); 
// Token is refreshed, now call getData() 
getData(callback); 
// Callback is run 

,或者,而不是使用一噸回調我可以同步執行refreshToken調用。但是,無論出於何種原因,WP7上的RestSharp都沒有顯示Execute,只是ExecuteAsync,這正是我現在使用的。有誰知道爲什麼這種方法似乎不適合我?

回答

3

有在Silverlight/WP7不同步Web調用,因此這不是一個restsharp問題。

正如亞瑟說你想要代表。

function getData(Action<string> callback) { 
    if (token.needRefresh) { 
    refrshToken(() => getData(callback)); 
    return; 
    } 
    // get Data 
    callback(data); 
} 

function refreshToken(Action callback) { 
    // token.refresh 
    callback(); 
} 
+0

完美的,謝謝你的例子。剛剛得到它的工作:) –

4

要在C#中傳遞函數作爲參數,請使用delegate。委託指定傳遞給方法的函數的期望返回類型和參數,並且回調方法必須符合此規範,否則您的代碼將無法編譯。

代表一般都是直接聲明的名稱空間內,並採取以下形式:

<access modifier(s)> delegate <return type> <DelegateName>([argument list]);

例如,在C#名爲FooCallback代表表示爲Foo方法,它沒有參數和返回void回調函數應該是這樣的:

namespace Demo 
{ 
public delegate void FooCallback(); 
} 

一個函數,一個FooCallback參數是這樣的:

namespace Demo 
{ 
//delegate for a FooCallback method from the previous code block 
public delegate void FooCallback(); 

public class Widget 
{ 
public void BeginFoo(FooCallback callback) 
{ 

} 

假設您有一個匹配委託簽名的方法,您可以簡單地將它的名稱作爲委託參數的值傳遞。例如,假設你有一個名爲MyFooCallback功能,您可以把它作爲一個參數傳遞給StartFoo方法是這樣的:

using Demo; //Needed to access the FooDelegate and Widget class. 

namespace YourApp 
{ 
public class WidgetUser 
{ 
private Widget widget; //initialization skipped for brevity. 

private void MyFooCallback() 
{ 
//This is our callback method for StartFoo. Note that it has a void return type 
//and no parameters, just like the definition of FooCallback. The signature of 
//the method you pass as a delegate parameter MUST match the definition of the 
//delegate, otherwise you get a compile-time error. 
} 
public void UseWidget() 
{ 
//Call StartFoo, passing in `MyFooCallback` as the value of the callback parameter. 
widget.BeginFoo(MyFooCallback); 
} 
} 
} 

雖然可以定義帶有參數的委託,就不可能將參數傳遞列表沿着方法名作爲一個正常調用方法

namespace Demo 
{ 
public delegate void FrobCallback(int frobberID); 
//Invalid Syntax - Can't pass in parameters to the delegate method this way. 
BeginFrob(MyFrobCallback(10)) 
} 

當委託指定的參數,調用該委託的方法時不採用由代表所需的參數,並把它們傳遞給委託方法被調用時:

然後

BeginFrob(MyFrobCallback, 10)

的BeginFrob方法是,像這樣的10傳入的frobberID值調用MyFrobCallback:

public void BeginFrob(FrobCallback callback, int frobberID) 
{ 
//...do stuff before the callback 
callback(frobberID); 
} 

Lambda Expressions允許你定義一個方法,它是用於而不需要明確聲明它

BeginFoo((int frobberID) => {your callback code here;});

總之,代表是一個裝置,用於將被傳遞方法來加時賽她的方法作爲參數。