什么是回调?

时间:2010-01-26 14:00:54

标签: c# callback

什么是回调?它是如何在C#中实现的?

11 个答案:

答案 0 :(得分:930)

我刚认识你,
这太疯狂了 但这是我的号码(代表),
因此,如果发生了某些事情(事件), 打电话给我,也许(回调)?

答案 1 :(得分:104)

  

computer programming中,回传为executable code,并以argument的形式传递给其他代码。

     

- Wikipedia: Callback (computer science)

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

答案 2 :(得分:66)

回调是一个在执行特定任务的过程中将被调用的函数。

回调的使用通常是异步逻辑。

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

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

答案 3 :(得分:45)

定义

  

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

实施

// 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

<强>链接

答案 4 :(得分:10)

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

查看this链接。

答案 5 :(得分:7)

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

  

在ASP.NET Web的默认模型中   页面,用户与页面交互   然后单击按钮或执行一些操作   导致a的其他行动   回发。页面及其控件   重新创建,页面代码运行   服务器,以及新版本的   页面呈现给浏览器。   但是,在某些情况下,它是   从中运行服务器代码很有用   客户端没有执行回发。   如果页面中的客户端脚本是   保持一些国家信息   (例如,局部变量值),   发布页面并获取新内容   它的副本破坏了那个状态。   此外,页面回发介绍   处理开销可以减少   性能并迫使用户等待   对于要处理的页面和   重新创建。

     

避免丢失客户端状态   招致a的处理开销   服务器往返,你可以编码   ASP.NET网页使它可以   执行客户端回调。在客户端   回调,客户端脚本函数   向ASP.NET发送请求   页。网页运行修改   正常生命周期的版本。该   页面已启动及其控件和   创建其他成员,然后创建一个   调用特别标记的方法。   该方法执行处理   您已编码然后返回一个   值可读取的浏览器   另一个客户端脚本函数。   在整个过程中,页面是   住在浏览器中。

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

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

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

此处有更多信息:http://msdn.microsoft.com/en-us/library/ms173172.aspx

答案 6 :(得分:4)

Dedication to LightStriker:  
Sample Code:
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();
    }       
}

Code Explanation:
I created the code to implement the funny explanation provided by    
LightStriker in the above one of the replies. We are passing 
delegate (number)   to a method (MetYourCrush). If the Interested
(event) occurs in the method (MetYourCrush) then it will call
the delegate (number) which was holding the reference of
CallMeBack method. So, the CallMeBack method will be called. 
Basically, we are passing delegate to call the callback method. 
Please let me know if you have any questions.

答案 7 :(得分:1)

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

示例可能是创建UI按钮时,它存储对执行操作的函数的引用。该操作由代码的不同部分处理,但是当按下该按钮时,将调用回调,并调用要执行的操作。

C#,而不是使用“回调”一词,使用“事件”和“委托”,您可以找到有关代表here的更多信息。

答案 8 :(得分:0)

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

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

Wikipedia

答案 9 :(得分: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点击调用EX函数的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),在文本服务器响应中,我们会得到。

答案 10 :(得分: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 ++中的作用与基于接口的回调相同,但是所造成的麻烦要少一些,因为您不必担心命名函数或创建辅助对象的麻烦,并且可以使委托脱离任何方法。它们更加灵活。