Callbacks in C#

2019-02-03 06:00发布

I want to have a library that will have a function in it that accepts an object for it's parameter.

With this object I want to be able to call a specified function when X is finished. The function that will be called is to be specified by the caller, and X will be done and monitored by the library.

How can I do this?

For reference I'm using C# and .NET 3.5

标签: c# .net callback
5条回答
地球回转人心会变
2楼-- · 2019-02-03 06:24

Sounds like a perfect recipe for delegates - in particular, callbacks with delegates are exactly how this is handled in the asynchronous pattern in .NET.

The caller would usually pass you some state and a delegate, and you store both of them in whatever context you've got, then call the delegate passing it the state and whatever result you might have.

You could either make the state just object or potentially use a generic delegate and take state of the appropriate type, e.g.

public delegate void Callback<T>(T state, OperationResult result)

Then:

public void DoSomeOperation(int otherParameterForWhateverReason,
                            Callback<T> callback, T state)

As you're using .NET 3.5 you might want to use the existing Func<...> and Action<...> delegate types, but you may find it makes it clearer to declare your own. (The name may make it clearer what you're using it for.)

查看更多
成全新的幸福
3楼-- · 2019-02-03 06:30

Supply a delegate and use an anonymous delegate or Lambda Expression

public static void DoWork(Action processAction)
{
  // do work
  if (processAction != null)
    processAction();
}

public static void Main()
{
  // using anonymous delegate
  DoWork(delegate() { Console.WriteLine("Completed"); });

  // using Lambda
  DoWork(() => Console.WriteLine("Completed"));
}

Or use an interface

public interface IObjectWithX
{
  void X();
}

public class MyObjectWithX : IObjectWithX
{
  public void X()
  {
    // do something
  }
}

public class ActionClass
{
  public static void DoWork(IObjectWithX handlerObject)
  {
    // do work
    handlerObject.X();
  }
}

public static void Main()
{
  var obj = new MyObjectWithX()
  ActionClass.DoWork(obj);
}
查看更多
相关推荐>>
4楼-- · 2019-02-03 06:30

Is there a reason not to have your library provide a public event to be fired when the operation is complete? Then the caller could just register to handle the event and you don't have to worry about passing around objects or delegates.

The object implementing an interface you have provided would work, but it seems to be more the Java approach than the .NET approach. Events seem a bit cleaner to me.

查看更多
女痞
5楼-- · 2019-02-03 06:35

The object in question will need to implement an interface provided by you. Take the interface as a parameter, and then you can call any method that the interface exposes. Otherwise you have no way of knowing what the object is capable of. That, or you could take a delegate as a parameter and call that.

查看更多
甜甜的少女心
6楼-- · 2019-02-03 06:39

You can use System.Action available in C#.NET for callback functions. Please check this sample example:

    //Say you are calling some FUNC1 that has the tight while loop and you need to 
    //get updates on what percentage the updates have been done.
    private void ExecuteUpdates()
    {
        Func1(Info => { lblUpdInfo.Text = Info; });
    }

    //Now Func1 would keep calling back the Action specified in the argument
    //This System.Action can be returned for any type by passing the Type as the template.
    //This example is returning string.
    private void Func1(System.Action<string> UpdateInfo)
    {
        int nCount = 0;
        while (nCount < 100)
        {
            nCount++;
            if (UpdateInfo != null) UpdateInfo("Counter: " + nCount.ToString());
            //System.Threading.Thread.Sleep(1000);
        }
    }
查看更多
登录 后发表回答