我可以使用System.Linq.Expressions动态生成异步方法吗?

Tho*_*que 18 c# linq code-generation expression-trees async-await

我知道编译器无法将异步lambda表达式转换为表达式树,但是可以手动生成表达式树吗?

var expr = Expression.Lambda<Func<Task>>(
     // how do I use 'await' in the body here?
);
var func = expr.Compile();
Run Code Online (Sandbox Code Playgroud)

我找不到相关的任何方法async或await在Expression类,但也许有另一种方式?

Mar*_*ell 17

await涉及重要的编译器重写; 生成的IL与原始的C#完全不同,包括变量提升(在类上)和分支,任务,延续等.尽管在.NET的最新版本中,它肯定不能用简单的 lambda 表示.有了更丰富的Expression支持(Expression.Block等等),从技术上来说,我认为它可能模仿编译器所做的大部分工作await- 但是你可能会试图用手工完成它.

不,AFAIK,没有自动化这种翻译的工具存在于ExpressionAPI中,坦率地说,我不会期望有.

同样可能是这样说的ILGenerator; 坦率地说,AFAIK唯一的"简单"方式(我使用"简单"这个词很不正确)用于await元编程将是生成C#并通过roslyn或者运行它CSharpCodeProvider.

  • 我怀疑它可以完成,只是因为应用于`async/await`的转换类似于自定义迭代器(`yield`)的转换,并且在`System.Linq.Expressions`上构建的DLR能够生成那种代码.不过,这不是一件小事.使用`Task.ContinueWith()`代替`await`可能会更好. (2认同)