什么是回调?


Answers:


123

计算机编程中,回调是可执行代码,作为参数传递给其他代码。

维基百科:回调(计算机科学)

C#为此有委托。它们与事件大量使用,因为事件可以自动调用许多附加的委托(事件处理程序)。


10
实际上,回调是指向作为其他代码的参数传递的可执行代码的指针...该页面需要审阅
Gianluca Ghettini 2014年

8
@G_G:没有什么可以说它必须是一个指针。通常是因为数据段不可执行,但从技术上讲,这是实现细节。
乔伊(Joey)2014年

乔伊:你是对的,这是一个实现细节,但即使回调也是实现细节。您可以在不使用单个回调的情况下重写代码。就像“ while”与“ for”一样。
Gianluca Ghettini 2014年

1051

我刚遇到你,
这太疯狂了,
但这是我的电话(委托),
所以,如果发生(事件),请
打电话给我,也许(回叫)?


33
完全很酷的解释。每当有人询问时,我都会使用此解释,希望我可以获得使用它的权利?
尼古拉·戴维多维奇

15
+1:喜欢。它破坏了歌曲,但是应该显示为“但这是我的电话号码以及使用特定类型的电话(代理)的说明”
Gone Coding

8
学习代表,脸上带着微笑:-)
Aakash

8
有史以来最好的解释!
zhengtonic 2014年

3
需要注意的是教学委托给其他人用这种解释只适用于一个很好的编排:)
塞巴斯蒂安Sevrin

87

回调是一个过程在完成特定任务后将被调用的函数。

回调的用法通常在异步逻辑中。

要在C#中创建回调,您需要将函数地址存储在变量中。这可以使用delegate或新的lambda语义Func或来实现Action

    public delegate void WorkCompletedCallBack(string result);

    public void DoWork(WorkCompletedCallBack callback)
    {
        callback("Hello world");
    }

    public void Test()
    {
        WorkCompletedCallBack callback = TestCallBack; // Notice that I am referencing a method without its parameter
        DoWork(callback);
    }

    public void TestCallBack(string result)
    {
        Console.WriteLine(result);
    }

在当今的C#中,可以使用lambda来完成此操作,例如:

    public void DoWork(Action<string> callback)
    {
        callback("Hello world");
    }

    public void Test()
    {
        DoWork((result) => Console.WriteLine(result));
    }

48

定义

一个回调是作为参数传递给其他代码通过可执行代码。

实作

// Parent can Read
public class Parent
{
    public string Read(){ /*reads here*/ };
}

// Child need Info
public class Child
{
    private string information;
    // declare a Delegate
    delegate string GetInfo();
    // use an instance of the declared Delegate
    public GetInfo GetMeInformation;

    public void ObtainInfo()
    {
        // Child will use the Parent capabilities via the Delegate
        information = GetMeInformation();
    }
}

用法

Parent Peter = new Parent();
Child Johny = new Child();

// Tell Johny from where to obtain info
Johny.GetMeInformation = Peter.Read;

Johny.ObtainInfo(); // here Johny 'asks' Peter to read

链接


2
您好@serhio谢谢您的回答。这对我来说仍然有点模糊:将代码作为参数传递给其他代码的确切位置似乎是在向孩子的委托人添加了Peter.Read方法?
BKSpurgeon '16

1
@serhio链接已死。
裘德

10

回调是传递给另一个函数的函数指针。您正在调用的函数完成后将“回调”(执行)另一个函数。

查看链接。


2
回调可以作为方法的委托来实现,但是您也可以说,在其接口上传递支持回调方法的对象就是回调。

Array.Sort(arrayObject); 在arrayObject的元素上调用obj.CompareTo(anotherObj)是在.Net中使用Interface(ICompareable)进行回调的经典示例。
Ron5504

8

如果您指的是ASP.Net回调:

在ASP.NET网页的默认模型中,用户与页面进行交互并单击按钮或执行某些其他操作导致回发。重新创建页面及其控件,页面代码在服务器上运行,并将新版本的页面呈现给浏览器。但是,在某些情况下,从客户端运行服务器代码而不执行回发很有用。如果页面中的客户端脚本正在维护某些状态信息(例如,局部变量值),则发布页面并获取其新副本将破坏该状态。此外,页面回发会导致处理开销,从而降低性能并迫使用户等待页面被处理和重新创建。

为了避免丢失客户端状态并且不招致服务器往返的处理开销,可以对ASP.NET网页进行编码,以便它可以执行客户端回调。在客户端回调中,客户端脚本功能将请求发送到ASP.NET网页。该网页运行其正常生命周期的修改版本。将启动该页面,并创建其控件和其他成员,然后调用一个特殊标记的方法。该方法执行您已经编码的处理,然后将值返回给浏览器,该值可以被另一个客户端脚本功能读取。在整个过程中,页面在浏览器中处于活动状态。

来源:http//msdn.microsoft.com/en-us/library/ms178208.aspx

如果您在代码中引用回调:

回调通常是特定方法完成或执行子操作时调用的方法的委托。您通常会在异步操作中找到它们。这是一种编程原理,几乎可以在每种编码语言中找到。

此处的更多信息:http : //msdn.microsoft.com/zh-cn/library/ms173172.aspx


4

致力于LightStriker:
示例代码:

class CallBackExample
{
    public delegate void MyNumber();
    public static void CallMeBack()
    {
        Console.WriteLine("He/She is calling you.  Pick your phone!:)");
        Console.Read();
    }
    public static void MetYourCrush(MyNumber number)
    {
        int j;
        Console.WriteLine("is she/he interested 0/1?:");
        var i = Console.ReadLine();
        if (int.TryParse(i, out j))
        {
            var interested = (j == 0) ? false : true;
            if (interested)//event
            {
                //call his/her number
                number();
            }
            else
            {
                Console.WriteLine("Nothing happened! :(");
                Console.Read();
            }
        }
    }
    static void Main(string[] args)
    {
        MyNumber number = Program.CallMeBack;
        Console.WriteLine("You have just met your crush and given your number");
        MetYourCrush(number);
        Console.Read();
        Console.Read();
    }       
}

代码说明:

我创建了代码,以实现上述答复之一中LightStriker提供的有趣解释。我们正在将委托(数字)传递给方法(MetYourCrush)。如果在方法()中发生了兴趣(事件)MetYourCrush,它将调用保存CallMeBack方法引用的委托(数字)。因此,该CallMeBack方法将被调用。基本上,我们将委托传递给回调方法。

请让我知道,如果你有任何问题。


这不能充分回答问题,您能否解释代码的作用,描述回调的工作方式以及如何在C#中实现回调。
亚当,

嗨,亚当,谢谢您的回复。我创建了代码来实现LightStriker提供的有趣解释。我们正在将委托(数字)传递给方法(MetYourCrush)。如果在方法(MetYourCrush)中发生有兴趣(事件),则它将调用保存CallMeBack方法的引用的委托(数字)。因此,将调用CallMeBack方法。基本上,我们将委托传递给回调方法。请让我知道,如果你有任何问题。
玛尼

1

可能不是字典定义,但回调通常是指一个函数,该函数在特定对象的外部存储并在发生特定事件时调用。

一个示例可能是在创建UI按钮时,它存储了对执行动作的功能的引用。该动作由代码的不同部分处理,但是当按下按钮时,将调用回调,这将调用该动作以执行。

C#而不是术语“回调”使用“事件”和“代理”,您可以在此处找到有关委托的更多信息。


0

回调使您可以将可执行代码作为参数传递给其他代码。在C和C ++中,这是作为函数指针实现的。在.NET中,您将使用委托来管理函数指针。

一些用途包括错误信令和控制功能是否起作用。

维基百科


0

回调工作步骤:

1)我们必须实现ICallbackEventHandler接口

2)注册客户端脚本:

 String cbReference = Page.ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");
    String callbackScript = "function UseCallBack(arg, context)" + "{ " + cbReference + ";}";
    Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "UseCallBack", callbackScript, true);

1)从UI调用Onclient单击调用javascript函数,例如: builpopup(p1,p2,p3...)

var finalfield = p1,p2,p3; UseCallBack(finalfield, ""); 使用UseCallBack从客户端传递到服务器端的数据

2) public void RaiseCallbackEvent(string eventArgument) 在eventArgument中,我们获取传递的数据//做一些服务器端操作并传递给“ callbackResult”

3) GetCallbackResult() //使用此方法将数据传递到客户端(ReceiveServerData()函数)端

callbackResult

4)在客户端获取数据: ReceiveServerData(text) 在文本服务器响应中,我们将获取。


0

委托的作用与C ++中基于接口的回调相同(COM使用这些回调),尽管使用起来更简单。

请注意,Microsoft将委托放入其Java实现(J ++)中,但是Sun不喜欢它们[java.sun.com],因此不要指望很快就会在Java的正式版本中看到它们。我已经整理好了一个预处理器,让您可以在C ++中使用它们,因此,如果您不是在C#或.NET平台上(即在Managed C ++或Visual Basic.NET中)编程,请不要感到被遗忘。

如果您习惯于使用C函数来编写指针,那么委托基本上就是一对变成一个指针的指针:

  • 指向对象的指针(可选)
  • 指向该对象的方法的指针

这意味着一个委托可以传递在程序中定位函数所需的所有信息,无论是静态方法还是与对象关联的函数。

您可以在C#中这样定义它们:

public delegate void FooCallbackType( int a, int b, int c );

当您要使用它们时,可以从要调用的函数中进行委托:

class CMyClass
{
    public void FunctionToCall( int a, int b, int c )
    {
        // This is the callback
    }

    public void Foo()
    {
        FooCallbackType myDelegate = new FooCallbackType(
            this.FunctionToCall );
        // Now you can pass that to the function
        // that needs to call you back.
    }
}

如果要使委托指向静态方法,则它看起来是一样的:

class CMyClassWithStaticCallback
{
    public static void StaticFunctionToCall( int a, int b, int c )
    {
        // This is the callback
    }

    public static void Foo()
    {
        FooCallbackType myDelegate = new FooCallbackType(
            CMyClass.StaticFunctionToCall );
    }
}

总而言之,它们的作用与C ++中基于接口的回调相同,但所带来的麻烦却少了一点,因为您不必担心命名函数或创建辅助对象的麻烦,并且可以使委托使用任何方法。它们更加灵活。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.