Roslyn能够编译await关键字吗?

8

在使用最新版本的时,我发现它不支持编译和脚本执行中的dynamic关键字,即您将会得到一个编译错误error CS8000: This language feature ('dynamic') is not yet implemented in Roslyn.以下是一个简短的代码片段:

var engine = new ScriptEngine();
var script = @"dynamic someVariable = 0;";
// you an error CS8000: This language feature ('dynamic') is not yet implemented in Roslyn
engine.CreateSession().Execute(script);

在使用await关键字时...

相比之下,在编译或脚本中使用await关键字时,我通常会遇到一些随机的编译错误,例如以下之一:

  • error CS1001: 需要标识符
  • error CS1003: 语法错误,需要 ','
  • error CS0246: 找不到类型或命名空间名称“await”(是否缺少 using 指令或程序集引用?)

脚本示例

var engine = new ScriptEngine();

new[]
{
    "System", "System.Threading", "System.Threading.Tasks",
} .ToList().ForEach(@namespace => engine.ImportNamespace(@namespace));

var script = @"await Task.Run(() => System.Console.WriteLine(""Universal [async] answer is '42'""));";

engine.CreateSession().Execute(script);

编译示例

// compilation sample
const string codeSnippet = @"namespace DemoNamespace
    {
        using System;
        using System.Threading;
        using System.Threading.Tasks;

        public class Printer
        {
            public async void Answer() 
            {
                var answer = 42;
                var task = Task.Run(() => System.Console.WriteLine(string.Format(""Universal [async] answer is '{0}'"", answer)));
                await task; // not working
                task.Wait(); // working as expected
            }
        }
     }";

var syntaxTree = SyntaxTree.ParseText(codeSnippet,
     options: new ParseOptions(languageVersion: LanguageVersion.CSharp5));

var references = new []
{
    MetadataReference.CreateAssemblyReference(typeof(Console).Assembly.FullName),
    MetadataReference.CreateAssemblyReference(typeof(System.Threading.Tasks.Task).Assembly.FullName),
};

var compilation = Compilation.Create(
                        outputName: "Demo", 
                        options: new CompilationOptions(OutputKind.DynamicallyLinkedLibrary),
                        syntaxTrees: new[] { syntaxTree },
                        references: references);

if(compilation.GetDiagnostics().Any())
{
    compilation.GetDiagnostics().Select(diagnostic => diagnostic).Dump();
    throw new Exception("Compilation failed");
}

Assembly compiledAssembly;
using (var stream = new MemoryStream())
{
    EmitResult compileResult = compilation.Emit(stream);
    compiledAssembly = Assembly.Load(stream.GetBuffer());
}

dynamic instance = Activator.CreateInstance(compiledAssembly.GetTypes().First());
instance.Answer();
问题: 我是不是漏掉了什么或者它还没有被实现?
我尝试了使用LanguageVersion.CSharp5和不使用的不同配置。谷歌和Stackoverflow搜索结果中充满了关键字的营销炒作,几乎毫无用处。Microsoft "Roslyn" CTP论坛也没有答案。
PS: 据我所知,async关键字是为了增加人类和编译器的可读性,而await则完成所有的魔法。
2个回答

9

当前的Roslyn CTP版本中尚未实现await支持(但在内部版本中已经实现)。

错误报告不同的原因是我们首先构建了Roslyn解析器,使其能够处理整个C# 4语言,然后逐一填充功能的语义。由于await是C# 5的功能,因此它甚至无法被解析器识别,并且没有地方识别其使用并提供良好的错误提示。


6
有计划发布这个内部版本(或者新的CTP)的时间表吗? - JustAnotherUserYouMayKnow
非常期待下一个代码版本的发布!我想要生成利用System.Net.Http.HttpClient异步支持的类。 - Cameron Taggart

5
实际上,Roslyn论坛确实有答案。如果您查看已知限制和未实现的语言功能帖子,您会注意到其中包括C#中尚未实现的“Async”功能。
那份清单是关于六月CTP的,但由于六月CTP和十二月CTP之间更改列表没有列出异步操作,这意味着它还没有实现。
我认为错误消息差异的原因是Roslyn确实理解dynamic(但尚未实现),另一方面,它不理解async-await,因此会给您通用的编译错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接