C#如何将Task.Factory.StartNew使用的无参Lambda设置为静态Lambda
解决方案
直接使用 Task.Factory.StartNew 自带的带state参数的重载即可,不需要自己封装静态方法,该重载就是为了避免闭包分配设计的,静态Lambda可以通过state参数拿到所有需要的上下文,不会捕获外部变量,也就不会生成临时闭包类实例。
代码示例
同步场景(AnswerOnRequest 无返回值)
Task.Factory.StartNew( static state => { // 把object类型的state拆箱为传入的三元组 var (parser, config, request) = ((TXRequestParser, AppMsgConfiguration, VdvKaLogic.Implementation.SoapReqMsg01V03))state; parser.AnswerOnRequest(config, request); }, // 把三个参数打包成值元组作为state传入 (parser, config, request) );
异步场景(AnswerOnRequest 返回Task)
如果你的AnswerOnRequest是异步方法,需要加Unwrap()处理嵌套的Task,否则会丢失异常且无法正确等待执行完成:
Task executeTask = Task.Factory.StartNew( static async state => { var (parser, config, request) = ((TXRequestParser, AppMsgConfiguration, VdvKaLogic.Implementation.SoapReqMsg01V03))state; await parser.AnswerOnRequest(config, request); }, (parser, config, request) ).Unwrap();
原封装方法无并行效果的原因
你自己写的ExecuteAnswerOnRequest是普通的静态方法,调用时是同步在当前线程执行的,没有提交到线程池调度,当然不会和调用栈并行执行,和静态Lambda本身无关。
优化原理
静态Lambda不捕获任何外部变量,编译器只会生成一次该委托的实例全局复用,所有上下文参数都通过state透传,只会产生一次值元组的装箱开销(.NET 高版本下该开销远小于闭包类的分配、GC开销),完全符合你避免每次调用生成新对象的需求。
内容的提问来源于stack exchange,提问作者Felix Arnold
相关产品推荐
相关产品推荐

