回调 复习 20250219

回调:通常是指,在另一个方法完成某项操作后调用某个方法。

下面是常见的回调实现方式

1.委托和事件

委托回调:委托是一个类型安全的函数指针,可以绑定多个方法

public delegate void MyCallback(string msg)

class Program
{
    static void Main()
   {
        MyCallback myCallback = new MyCallback(CallbackMethod);
        ExecuteTask(myCallback);
   }

    static void ExecuteTask(MyCallback callback)
    {
        //做某些操作
        Console.WriteLine("Task completed");

        callback("execute callback method");
    }

    static void CallbackMethod(string message)
    {
        Console.WriteLine($"Callback received: {message}");
    }

}

那么就有人要问了,下面这两种调用有区别吗?

//调用方式一
static void ExecuteTask(MyCallback callback)
{
    // 模拟一些任务完成后的回调
    Console.WriteLine("Task completed!");
    callback("Task is complete!");
}


//调用方式二
static void ExecuteTask(MyCallback callback)
{
    // 模拟一些任务完成后的回调
    Console.WriteLine("Task completed!");
    Program.CallbackMethod("Task is complete!");
}

我的回答是:有的兄弟,有的

callback是一个委托,它具有一定的灵活性,即,如果我们在创建这个实例时,通过给他传递不同的方法,可以在ExecuteTask里执行不同的方法

    static void Main()
   {
        MyCallback myCallback = new MyCallback(CallbackMethod);
        ExecuteTask(myCallback);

        MyCallback myCallback2 = new MyCallback(DontCallbackMethod);
        ExecuteTask(myCallback2);
   }

回调方法可以是外部方法,可以传入任何符合MyCallback委托签名的方法,包括在外部类中的方法

事件回调:  基于委托的一种更高级的机制,用于实现发布/订阅模式,事件可以通知订阅者某个操作的实现

public class Publisher
{
    public event Action<string> OnCompleted;

    public void ExecuteTask()
    {
        //模拟任务执行
        Console.WriteLine("task is in progress...");

        //任务完成,通知订阅者,并传递信息"task completed!"
        OnCompleted?.Invoke("task completed!");
    }
}

class program
{
    static void Main()
    {
        Publisher publisher = new Publisher();

        publisher.OnCompleted += CallbackMethod;    //订阅类里的事件

        publisher.ExecuteTask(); //执行该方法,当执行到invoke那一步的时候就通知订阅者
    }

    static void CallbackMethod(string obj)
    {
        Console.WriteLine($"callback reveived:{obj}");
    }
}

2.UI线程回调(Invoke)

using System;
using System.Windows.Forms;

class Program
{
    static void Main()
    {
        Form form = new Form();
        Button button = new Button();
        button.Text = "Click Me!";
        button.Click += Button_Click;

        form.Controls.Add(button);
        Application.Run(form);
    }

    private static void Button_Click(object sender, EventArgs e)
    {
        //是否是UI线程操作
        if (sender is Control control && control.InvokeRequired)
        {
            //启用Ui线程执行该方法
            control.Invoke(new Action(() => MessageBox.Show("Button clicked!")));
        }
        else
        {
            MessageBox.Show("Button clicked!");
        }
    }
}

3. Task和async/await 异步回调   最常用

async和await 可以取代大部分的回调机制

***NOTE***

async/await是Task的语法糖,他们虽然不创建新的线程,但是可以把当前线程挂起,让CPU去执行其他事情,让异步执行起来和同步一样。

Task是基于线程池(ThreadPool)的,通过Task.run()提交任务时,会在线程池中运行。

async/await又是基于回调机制的,当在方法中使用await语句,await会在任务未完成是注册一个回调。当任务完成是,回来继续执行方法后续的代码。

using System;
using System.Threading;
using System.Threading.Tasks;
class program
{
    static async void Main()
    {
        await ExecuteTaskAsync();
        ExecuteTask();
    }

    private static void ExecuteTask()
    {
        Console.WriteLine("task started");
        Thread.Sleep(1000); 
        Console.WriteLine("task completed");
        DirectMethod("Task is complete!");
    }

    private static void DirectMethod(string v)
    {
        Console.WriteLine($"received:{v}");
    }

    static async Task ExecuteTaskAsync()
    {
        Console.WriteLine("task started");
        await TimeConsumTask(1000); //模拟异步操作
        Console.WriteLine("task completed");
        CallbackMethod("Task is complete!");
    }

    private static async Task TimeConsumTask(int v)
    {
        await Task.Delay(v);
    }

    private static void CallbackMethod(string v)
    {
        Console.WriteLine($"callback received:{v}");
    }
}

4. Action和Func (内联委托) 

ActionFunc是C#内置的委托类型,Action用于没有返回值的回调,Func用于有返回值的回调。

Action回调
class Program
{
    static void Main()
    {
        Action<string> callback = message => Console.WriteLine($"Callback received: {message}");
        ExecuteTask(callback);
    }

    static void ExecuteTask(Action<string> callback)
    {
        Console.WriteLine("Task completed!");
        callback("Task is complete!");
    }
}

//本质上下面这个没有区别的
class Program3
{
    static void Main()
    {
        MyCallback myCallback = new MyCallback(CallbackMethod);
        ExecuteTask(myCallback);
    }

    static void ExecuteTask(MyCallback callback)
    {
        Console.WriteLine("Task completed");
        callback("Task is complete!");
    }

    static void CallbackMethod(string message)
    {
        Console.WriteLine($"Callback received: {message}");
    }
}

Func回调和Action回调的差别就是有返回值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值