开发者

Callback Functions in C#

I am used to Javascript where I can simply pass a function as a parameter to use as a callback later. It was nice and easy.

Now I am writing an app in c# and would like to accomplish the same thing.

Basically, my app is like the following and requires an authentication token. However, at the getData stage, if the token is expired, I need to call refreshToken(). How do I pass the callback function through refreshToken() so getData knows what to call when the token is refreshed?

Here's a diagram of what I would do in Javascript, but would I go about doing this in C#, or just passing callbacks in general?:

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

Or, alternatively, instead of using a ton of callbacks I could do the refreshToken call sync开发者_JAVA百科hronously. However, RestSharp on WP7 for whatever reason isn't showing Execute, just ExecuteAsync, which is what I use now. Does anyone know why this method doesn't seem to exist for me?


To pass a function as a parameter in C# one uses a delegate. A delegate specifies the expected return type and arguments of the function being passed into a method and your callback method must conform to this specification, otherwise your code will not compile.

Delegates are generally declared directly within a namespace and take the form:

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

For example, in C# a delegate named FooCallback representing a callback function for the Foo method that takes no arguments and returns void would look like this:

namespace Demo
{
public delegate void FooCallback();
}

A function that takes a FooCallback parameter would look like this:

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

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

}

Asssuming that you have a method that matches the signature of a delegate you can simply pass it's name as the value of the delegate parameter. For example, assuming you have a function named MyFooCallback you can pass it as a parameter to the StartFoo method like this:

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);
}
}
}

While it is possible to define a delegate with arguments, it is not possible to pass an argument list alongside the method name as one normally does when invoking a method

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

When a delegate specifies parameters, the method that invokes the delegate takes the arguments needed by the delegate and passes them to the delegate method when it is called:

BeginFrob(MyFrobCallback, 10)

The BeginFrob method would then invoke the MyFrobCallback with the passed in frobberID value of 10 like this:

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

Lambda Expressions allow you to define a method where it is used rather than needing to explicitly declare it

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

In summary, delegates are a means for methods to be passed to other methods as parameters.


There are no synchronous web calls in silverlight / wp7, so that is not a restsharp problem.

As arthur said you want delegates.

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

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


What you're looking for is delegate, anonymous delegate or Func

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜