C# C语言中的回调#

C# C语言中的回调#,c#,.net,callback,C#,.net,Callback,我想有一个库,其中有一个函数,它接受一个对象作为它的参数 有了这个对象,我希望能够在X完成时调用指定的函数。调用方将指定要调用的函数,库将完成并监视X 我该怎么做 作为参考,我使用的是C#和.NET 3.5这个对象需要实现您提供的接口。将接口作为参数,然后可以调用接口公开的任何方法。否则,您无法知道对象的功能。或者你可以把一个委托作为一个参数并调用它。听起来像是一个完美的委托方法——特别是,委托回调正是在.NET的异步模式中处理这个问题的方式 调用方通常会向您传递一些状态和一个委托,您可以将它们

我想有一个库,其中有一个函数,它接受一个对象作为它的参数

有了这个对象,我希望能够在X完成时调用指定的函数。调用方将指定要调用的函数,库将完成并监视X

我该怎么做


作为参考,我使用的是C#和.NET 3.5

这个对象需要实现您提供的接口。将接口作为参数,然后可以调用接口公开的任何方法。否则,您无法知道对象的功能。或者你可以把一个委托作为一个参数并调用它。

听起来像是一个完美的委托方法——特别是,委托回调正是在.NET的异步模式中处理这个问题的方式

调用方通常会向您传递一些状态和一个委托,您可以将它们存储在任何上下文中,然后调用传递状态和结果的委托

您可以将状态设置为仅
对象
,或者可能使用泛型委托并采用适当类型的状态,例如

public delegate void Callback<T>(T state, OperationResult result)
公共委托无效回调(T状态,操作结果)
然后:

public void DoSomeOperation(无论出于何种原因,输入其他参数),
回调(T状态)
在使用.NET 3.5时,您可能希望使用现有的
Func
Action

委托类型,但您可能会发现声明自己的委托类型更为清晰。(名称可能会让您更清楚地知道使用它的目的。)

是否有理由不让您的库提供在操作完成时触发的公共事件?然后调用方可以注册来处理事件,而不必担心传递对象或委托

实现您提供的接口的对象可以工作,但它似乎更像是Java方法而不是.NET方法。事件对我来说似乎有点干净。

有两个选项供您选择:

  • 让函数接受(对于不返回任何内容的回调,对于返回任何内容的回调),并在调用它时使用匿名委托或Lambda表达式

  • 使用接口

  • 使用委托/lambda 如果回调需要向其传递某些内容,则可以在
    操作
    上使用类型参数:

    public static void DoWork(Action<string> processAction)
    {
      // do work
      if (processAction != null)
        processAction("this is the string");
    }
    
    public static void Main()
    {
      // using anonymous delegate
      DoWork(delegate(string str) { Console.WriteLine(str); });
    
      // using Lambda
      DoWork((str) => Console.WriteLine(str));
    }
    

    您可以使用C#.NET中提供的System.Action执行回调函数。请检查此示例:

        //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);
            }
        }
    
    //假设您正在调用具有紧密while循环的FUNC1,您需要
    //获取更新完成百分比的更新。
    私有void ExecuteUpdates()
    {
    Func1(Info=>{lblUpdInfo.Text=Info;});
    }
    //现在Func1将继续回调参数中指定的操作
    //通过将类型作为模板传递,可以为任何类型返回此System.Action。
    //此示例返回字符串。
    私有void Func1(System.Action UpdateInfo)
    {
    int nCount=0;
    而(n计数<100)
    {
    nCount++;
    如果(UpdateInfo!=null)UpdateInfo(“计数器:+nCount.ToString());
    //系统线程线程睡眠(1000);
    }
    }
    
    我怀疑您的答案包含degate、events或两者。然而,在读了几遍你的问题之后,我无法理解你的问题。下面是一个示例,可以了解一些事件。它们可能适合您的情况,也可能不适合您的情况,但它们值得了解。我建议您阅读一下学员的相关内容(可能还有泛型)。我关于委托和EVENTS的文章是,这不是回调的替代方案;这是一次回访。我冒昧地对这个极好的答案进行了一些扩展,这些扩展在我找到答案时会对我有所帮助。显然,如果你不喜欢这些变化,请后退。无论如何谢谢你的帮助!
    public static void DoWork(Action<string> processAction)
    {
      // do work
      if (processAction != null)
        processAction("this is the string");
    }
    
    public static void Main()
    {
      // using anonymous delegate
      DoWork(delegate(string str) { Console.WriteLine(str); });
    
      // using Lambda
      DoWork((str) => Console.WriteLine(str));
    }
    
    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);
    }
    
        //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);
            }
        }