2025-05-12 05:00:00

什么是回调?

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


当前回答

如果您指的是ASP。净回调函数:

In the default model for ASP.NET Web pages, the user interacts with a page and clicks a button or performs some other action that results in a postback. The page and its controls are re-created, the page code runs on the server, and a new version of the page is rendered to the browser. However, in some situations, it is useful to run server code from the client without performing a postback. If the client script in the page is maintaining some state information (for example, local variable values), posting the page and getting a new copy of it destroys that state. Additionally, page postbacks introduce processing overhead that can decrease performance and force the user to wait for the page to be processed and re-created. To avoid losing client state and not incur the processing overhead of a server roundtrip, you can code an ASP.NET Web page so that it can perform client callbacks. In a client callback, a client-script function sends a request to an ASP.NET Web page. The Web page runs a modified version of its normal life cycle. The page is initiated and its controls and other members are created, and then a specially marked method is invoked. The method performs the processing that you have coded and then returns a value to the browser that can be read by another client script function. Throughout this process, the page is live in the browser.

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

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

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

更多信息请访问:http://msdn.microsoft.com/en-us/library/ms173172.aspx

其他回答

我才刚认识你, 这很疯狂, 这是我的number (delegate) 所以如果发生了什么(事件), 打给我吧(回电话)?

定义

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

实现

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

链接

c#的更多细节。

回调是作为参数传递给另一个函数的函数。这种技术允许函数调用形参函数实参,甚至将值传递回调用方。回调函数可以设计为在函数结束之前/之后运行,并且可以传递一个值。

它是一种构造,你调用一个长时间运行的函数,并要求他在它完成后回调你,可以返回一个参数结果给调用者。

这就像有人在你工作的时候打电话给你询问状态,你说“你知道吗,给我5分钟,我会给你回电”,最后你打电话给他更新情况。如果你是一个函数,调用者只是添加并传递了另一个你在最后调用的函数。这可以简单地用c#编写为:

public void VinodSrivastav(Action statusUpdate){
    //i am still here working..working

    //i have finished, calling you
    statusUpdate();
}

//invokes
stackoverflow.VinodSrivastav((cam) => { 
    Console.Write("Is it finished"); 
});

一个简单的例子是迭代器函数,其中的return将是多次,可以认为我们为它设置了yield:

public void IntreationLoop(int min, int max,Action<int> Callback)
{
    for(int i = min;i<= max;i++)
        Callback(i);
}

//call
IntreationLoop(5,50,(x) => { Console.Write(x); }); //will print 5-50 numbers

在上面的代码中,函数返回类型为void,但它有一个Action<int>回调函数,该回调函数被调用,并将循环中的每个项发送给调用者。

同样的事情也可以用if..else或try..catch block as:

public void TryCatch(Action tryFor,Action catchIt)
{
    try{
        tryFor();
    }
    catch(Exception ex)
    {
        Console.WriteLine($"[{ex.HResult}] {ex.Message}");
        catchIt();
    }
}

称之为:

TryCatch(()=>{ 
        int r = 44;
        Console.WriteLine("Throwing Exception");
        throw new Exception("something is wrong here");
    }, ()=>{
        Console.WriteLine("It was a mistake, will not try again");
    });

在2022年,我们有Func和Action做同样的事情,请参阅下面的演示代码,其中展示了如何使用它:

void Main()
{
    var demo = new CallbackDemo();
    demo.DoWork(()=> { Console.WriteLine("I have finished the work"); });
    demo.DoWork((r)=> { Console.WriteLine($"I have finished the work here is the result {r}"); });
    demo.DoWork(()=> { Console.WriteLine($"This is passed with func"); return 5;});
    demo.DoWork((f)=> { Console.WriteLine($"This is passed with func and result is {f}"); return 10;});
    
}

// Define other methods and classes here
public class CallbackDemo
{

    public void DoWork(Action actionNoParameter)
    {
        int a = 5;
        int b = 10;
        
        //i will do th maths and call you back
        int result = a + b;
        
        //callback
        actionNoParameter(); //execute
        Console.WriteLine($"[The Actual Result is {result}]");
    }
    
    public void DoWork(Action<int> actionWithParameter)
    {
        int a = 5;
        int b = 10;
        
        //i will do th maths and call you back
        int result = a + b;
        
        //callback
        actionWithParameter(result); //execute
        Console.WriteLine($"[The Actual Result is {result}]");
    }
    
    public void DoWork(Func<int> funcWithReturn)
    {
        int a = 5;
        int b = 10;
        
        //i will do th maths and call you back
        int result = a + b;
        
        //callback
        int c = funcWithReturn(); //execute
        
        result += c;
        Console.WriteLine($"[The Actual Result is {result}]");
    }
    
    public void DoWork(Func<int,int> funcWithParameter)
    {
        int a = 5;
        int b = 10;
        
        //i will do th maths and call you back
        int result = a + b;
        
        //callback
        result += funcWithParameter(result); //execute
        Console.WriteLine($"[The Actual Result is {result}]");
    }
}

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

例如,当创建一个UI按钮时,它存储了对执行某个操作的函数的引用。该操作由代码的不同部分处理,但当按下按钮时,将调用回调,这将调用要执行的操作。

c#使用“事件”和“委托”而不是“回调”这个术语,你可以在这里找到更多关于委托的信息。

对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方法会被调用。基本上,我们传递委托来调用回调方法。

如果你有任何问题,请告诉我。