Invoke和BeginInvoke

  UI控件
    Invoke:在拥有此控件句柄的线程上执行指定的委托。
    BeginInvoke:在拥有此控件句柄的线程上异步执行指定的委托。
    场景描述:进度条

private void btnDownload_Click(object sender, EventArgs e)
{
    Thread downloadThread = new Thread(() =>
    {
        for (int i = 1; i <= 100; i++)
        {
            Thread.Sleep(50); // 模拟下载进度

            // 同步更新 UI
            labelProgress.Invoke((MethodInvoker)(() =>
            {
                labelProgress.Text = $"进度: {i}%";
            }));

            // 异步更新 UI(更常用,避免阻塞后台线程)
            labelProgress.BeginInvoke((MethodInvoker)(() =>
            {
                progressBar1.Value = i;
            }));
        }
    });
    downloadThread.Start();
}

Invoke:阻塞后台线程直到UI更新完成。
BeginInvoke:异步更新UI,不阻塞,更流程。

  委托
   委托用于事件处理、回调函数、LINQ等操作。通俗就是委托就是“方法的容器”,你可以把方法当成参数传来传去、在运行时决定调用那个方法,这就是委托的意义。

using System;
using System.Threading;

class Program
{
    // 定义一个委托类型
    delegate int Compute(int a, int b);

    static void Main()
    {
        // 创建委托实例(可以指向任何符合签名的方法)
        Compute compute = (a, b) =>
        {
            Console.WriteLine($"[{Thread.CurrentThread.ManagedThreadId}] 开始计算...");
            Thread.Sleep(2000);
            return a + b;
        };

        // 同步调用
        Console.WriteLine("同步调用开始");
        int syncResult = compute.Invoke(10, 20);
        // int syncResult = compute(10,20); 等同上面写法
        Console.WriteLine($"同步结果:{syncResult}");

        // 步调用(BeginInvoke)
        Console.WriteLine("\n异步调用开始");
        IAsyncResult asyncResult = compute.BeginInvoke(100, 200, null, null);
        // 带回调参数的这种不常用
        // IAsyncResult asyncResult = compute.BeginInvoke(100, 200, CallbackMethod, new { A = 10, B = 20 });
        Console.WriteLine("主线程继续执行...");
        // 等后台线程执行完,从异步结果中取返回值 EndInvoke会阻塞他的调用线程,所以要么不取结果,要么单独线程中取结果。
        int asyncValue = compute.EndInvoke(asyncResult);
        Console.WriteLine($"异步结果:{asyncValue}");
    }
    static void CallbackMethod(IAsyncResult ar)
    {
    		var state = (dynamic)ar.AsyncState;
    		int a = state.A;
    		int b = state.B;

    		AsyncResult result = (AsyncResult)ar;
    		Compute compute = (Compute)result.AsyncDelegate;
    		int sum = compute.EndInvoke(ar);

    		Console.WriteLine($"回调:a={a}, b={b}, sum={sum}");
		}
}

现在C#里面基本不使用委托的BeginInvoke。而是用Task+asyn/await

async Task<int> ComputeAsync(int a, int b)
{
    return await Task.Run(() =>
    {
        Thread.Sleep(2000);
        return a + b;
    });
}

async Task Test()
{
    Console.WriteLine("主线程继续执行...");
    int result = await ComputeAsync(10, 20);
    Console.WriteLine($"结果:{result}");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值