Roslyn可以编译await关键字吗?

Aki*_*kim 8 c# async-await c#-5.0 roslyn

在使用最新版本的我发现它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);
Run Code Online (Sandbox Code Playgroud)

使用await关键字时......

相反,await在编译或脚本中使用关键字时,我通常会遇到一些随机编译错误,如下所示:

  • error CS1001: Identifier expected
  • error CS1003: Syntax error, ',' expected
  • error CS0246: The type or namespace name 'await' could not be found (are you missing a using directive or an assembly reference?)

脚本示例

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);
Run Code Online (Sandbox Code Playgroud)

编译样本

// 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();
Run Code Online (Sandbox Code Playgroud)

问:我错过了什么或者没有实现吗?

我有没有尝试过不同的配置LanguageVersion.CSharp5.Google和Stackoverflow搜索都充斥着针对和关键字的营销宣传,几乎无用.微软"Roslyn"CTP论坛也没有答案.

ps:据我所知,async关键字是为了人类和编译器的可读性而引入的,同时await具有所有魔力

Kev*_*lch 9

await 当前的Roslyn CTP中没有实现支持(尽管现在在内部版本中实现).

错误报告差异的原因是我们首先构建了Roslyn解析器,以便它可以处理整个C#4语言,然后一次填充一个功能的语义.由于await是C#5功能,解析器甚至无法识别它,因此无法识别其使用并提供良好的错误.

  • 什么时候发布这个内部构建(或新的CTP)的计划? (6认同)

svi*_*ick 5

实际上,罗斯林论坛确实有答案.如果您查看帖子已知限制和未实现的语言功能,您会注意到它在C#中尚未实现的功能中包含"异步".

该列表是关于6月CTP的,但由于6月CTP和12月CTP之间的更改列表没有列出异步,这意味着它尚未实现.

我认为错误消息不同的原因是Roslyn确实理解dynamic(但尚未实现).另一方面,它不理解async- await,因此它给你通用的编译错误.