委托(4)

并行委托

并行委托有Parallel.For()、Parallel.Foreach<>()、Parallel.Invoke()三种写法,应用并行可以缩短程序运行时间。
Parallel.For()写法:

static void Main(string[] args)
{
    Stopwatch watch = new Stopwatch();
    watch.Start();
    //【写法一】
    //Parallel.For(1, 11, new DelegateHelper().Test);
    //【写法二】
    Parallel.For(1, 11, delegate(int i) { 
        Console.WriteLine(i); Thread.Sleep(1000); 
    });
    watch.Stop();
    //非并行情况下循环10次需要10s,因为每次执行Test方法会休息1s
    Console.WriteLine("花费时间:" + watch.Elapsed.Seconds);
    Console.ReadKey();
}
public void Test(int num)
{
    Console.WriteLine(num);
    Thread.Sleep(1000);
}

运行截图如下:
这里写图片描述
Parallel.Foreach<>()写法:

static void Main(string[] args)
{
    Stopwatch watch = new Stopwatch();
    watch.Start();
    //【写法一】
    int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    string[] strArray = { "a","b","c","d","e","f","g"};
    //Parallel.ForEach<int>(nums, new DelegateHelper().Test);
    //【写法二】
    Parallel.ForEach<int>(nums, delegate(int num)
    {
        Console.WriteLine(num);
        Thread.Sleep(1000);
    }); 
    //遍历string数组
    Parallel.ForEach<string>(strArray, delegate(string str)
    {
        Console.WriteLine(str);
        Thread.Sleep(1000);
    }); 
    watch.Stop();
    //非并行情况下循环10次需要10s,因为每次执行Test方法会休息1s
    Console.WriteLine("花费时间:" + watch.Elapsed.Seconds);
    Console.ReadKey();
}
public void Test(int num)
{
    Console.WriteLine(num);
    Thread.Sleep(1000);
}

运行结果如下:
这里写图片描述
Parallel.Invoke()写法:

static void Main(string[] args)
{
    Stopwatch watch = new Stopwatch();
    watch.Start();
    //【写法一】
    Action[] actions=new Action[]{
        new Action(delegate(){Console.WriteLine("方法一");Thread.Sleep(1000);}),
        new Action(delegate(){Console.WriteLine("方法二");Thread.Sleep(1000);}),
        new Action(delegate(){Console.WriteLine("方法三");Thread.Sleep(1000);})
    };
    Parallel.Invoke(actions);
    //【写法二】
    Parallel.Invoke(Func1, Func2, Func3);  
    watch.Stop();
    //非并行情况下循环10次需要10s,因为每次执行Test方法会休息1s
    Console.WriteLine("花费时间:" + watch.Elapsed.Seconds);
    Console.ReadKey();
}
public static void Func1()
{
    Console.WriteLine("方法一"); Thread.Sleep(1000);
}
public static void Func2()
{
    Console.WriteLine("方法二"); Thread.Sleep(1000);
}
public static void Func3()
{
    Console.WriteLine("方法三"); Thread.Sleep(1000);
}

运行截图如下:
这里写图片描述

异步委托

异步委托可以异步执行委托的方法,不过是用EndInvoke()方法等待委托执行完毕然后获取返回值。
EndInvoke()会阻塞主线程,等到委托的方法执行完毕后,程序才会继续执行,不过EndInvoke()之前的代码会正常执行,一般用于执行相互独立的模块,BeginInvoke异步执行独立模块A,BeginInvoke之后EndInvoke之前执行独立模块B,等到两模块都执行完毕后来进行下一步的操作,这样可以提高一点效率。
没有回调函数:

public void AsyncDelegateNoCallback()
{
    SayHiEventHandler sayHi = SayHiByChinese;
    IAsyncResult iasyncResult = sayHi.BeginInvoke("蝈蝈", null, null);
    Console.WriteLine("do some things......");
    //有EndInvoke结果如图一,没EndInvoke结果如图二
    //string result = sayHi.EndInvoke(iasyncResult);
    Console.WriteLine("继续执行");
}
public string SayHiByChinese(string name)
{
    Console.WriteLine("你好:" + name);
    Thread.Sleep(2000);
    return "成功";
}

这里写图片描述
这里写图片描述
有回调函数:
异步委托所需的回调函数其实就是无返回值、包含一个IAsyncResult类型参数的委托。
回调函数是在委托执行完毕之后才执行,此时EndInvoke()将不会再花费大量时间,因为委托已经执行完毕可直接获取结果。

public void AsyncDelegate()
{
    SayHiEventHandler sayHi = SayHiByChinese;
    IAsyncResult iasyncResult = sayHi.BeginInvoke("蝈蝈",CallBackFunc,"回调函数所需参数");    
    //回调函数中有EndInvoke,此处不应该再写一次
    //sayHi.EndInvoke(iasyncResult);
    Console.WriteLine("继续执行主线程");
}

public void AsyncDelegateAnonymous()
{
    SayHiEventHandler sayHi = SayHiByChinese;
    IAsyncResult iasyncResult = sayHi.BeginInvoke("蝈蝈", new AsyncCallback(delegate(IAsyncResult ias) {
        AsyncResult asyncResult = ias as AsyncResult;
        //param="回调函数所需参数"
        string param = asyncResult.AsyncState.ToString();
        SayHiEventHandler current = asyncResult.AsyncDelegate as SayHiEventHandler;
        Console.WriteLine("do other things......");
        //result="成功"
        string result = current.EndInvoke(asyncResult);
        Console.WriteLine("继续执行回调函数");
    }), "回调函数所需参数");     
    //回调函数中有EndInvoke,此处不应该再写一次
    //sayHi.EndInvoke(iasyncResult);
    Console.WriteLine("继续执行主线程");
}
public void CallBackFunc(IAsyncResult ias)
{
    AsyncResult asyncResult = ias as AsyncResult;
    //param="回调函数所需参数"
    string param = asyncResult.AsyncState.ToString();
    SayHiEventHandler current = asyncResult.AsyncDelegate as SayHiEventHandler;
    Console.WriteLine("do other things......");
    //result="成功"
    string result = current.EndInvoke(asyncResult);
    Console.WriteLine("继续执行回调函数");
}

运行结果如图:
这里写图片描述

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

changuncle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值