如何让新的异步语义在 VS2017 RC 中工作?
How do I get the new async semantics working in VS2017 RC?
引用自Visual Studio 2017 RC Release Notes
Language Extensions and Analyzers
This release includes some proposed new language extensions that we are working on for the next versions of C# and Visual Basic. These new language features are enabled by default and include:
For C#:
- Task-like return types for async methods: This introduces the ability to return any task-like type from an async method. Previously these return types were constrained to
Task<T>
and Task
.
它说它默认启用,但我无法让它工作。即使从链接的 Github 页面获取确切的 ArbitraryAsyncReturns.zip 下载(并修复对 React NuGet 包的引用以删除不相关的错误),但没有安装自定义 VSIX 包(适用于 VS2015),我继续获得
error CS1983: The return type of an async method must be void, Task or Task<T>
我是否需要采取任何其他步骤才能使其正常工作?
我首先尝试将那个特定示例缩减为应该可以工作的最小版本,但尝试使用它时,我还不知道什么应该工作,什么不应该工作。至少,考虑到这种语言的增强,我预计会出现一个伪造的程序,例如
struct Test { }
static class Program {
static async Test Test() { }
static void Main() { }
}
编译失败并显示不同的错误消息。即使在那时收到相同的错误消息表明此语言扩展尚未启用,但 JaredPar 注意到错误消息尚未更新。
我现在将其中一个假定有效的示例缩减为我认为应该编译的最小版本(但由于未实现的方法,在 运行 时失败),但不编译:
using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace System.Runtime.CompilerServices {
public class TasklikeAttribute : Attribute {
public TasklikeAttribute(Type builderType) { }
}
}
struct TasklikeTypeMethodBuilder<T> {
public static TasklikeTypeMethodBuilder<T> Create() => throw new NotImplementedException();
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine => throw new NotImplementedException();
public void SetStateMachine(IAsyncStateMachine stateMachine) => throw new NotImplementedException();
public void SetResult(T result) => throw new NotImplementedException();
public void SetException(Exception exception) => throw new NotImplementedException();
public TasklikeType<T> Task => throw new NotImplementedException();
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine => throw new NotImplementedException();
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine => throw new NotImplementedException();
}
[Tasklike(typeof(TasklikeTypeMethodBuilder<>))]
struct TasklikeType<T> { }
static class Program {
static void Main(string[] args) { }
static async TasklikeType<string> TasklikeTypeTester() {
await Task.Yield();
return "hello";
}
}
为 static async TasklikeType<string> TasklikeTypeTester()
.
生成与上述相同的编译器错误
您无需执行任何其他操作即可启用类任务 returns。这里的问题是此功能的诊断消息尚未更新。这是跟踪问题的 link:
TasklikeAttribute
属性名称原来不是 VS2017 RC 中实现的,而是来自提案的不同版本。实际实现的内容依赖于一种类型 System.Runtime.CompilerServices.AsyncMethodBuilderAttribute
,其工作方式似乎完全相同。
我找不到这个文档,但我能在 Roslyn 测试中找到它,例如 CodeGenAsyncTests.cs:
[AsyncMethodBuilder(typeof(ValueTaskMethodBuilder))]
struct ValueTask { }
...
namespace System.Runtime.CompilerServices { class AsyncMethodBuilderAttribute : System.Attribute { public AsyncMethodBuilderAttribute(System.Type t) { } } }
引用自Visual Studio 2017 RC Release Notes
Language Extensions and Analyzers
This release includes some proposed new language extensions that we are working on for the next versions of C# and Visual Basic. These new language features are enabled by default and include:
For C#:
- Task-like return types for async methods: This introduces the ability to return any task-like type from an async method. Previously these return types were constrained to
Task<T>
andTask
.
它说它默认启用,但我无法让它工作。即使从链接的 Github 页面获取确切的 ArbitraryAsyncReturns.zip 下载(并修复对 React NuGet 包的引用以删除不相关的错误),但没有安装自定义 VSIX 包(适用于 VS2015),我继续获得
error CS1983: The return type of an async method must be void, Task or Task<T>
我是否需要采取任何其他步骤才能使其正常工作?
我首先尝试将那个特定示例缩减为应该可以工作的最小版本,但尝试使用它时,我还不知道什么应该工作,什么不应该工作。至少,考虑到这种语言的增强,我预计会出现一个伪造的程序,例如
struct Test { }
static class Program {
static async Test Test() { }
static void Main() { }
}
编译失败并显示不同的错误消息。即使在那时收到相同的错误消息表明此语言扩展尚未启用,但 JaredPar 注意到错误消息尚未更新。
我现在将其中一个假定有效的示例缩减为我认为应该编译的最小版本(但由于未实现的方法,在 运行 时失败),但不编译:
using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace System.Runtime.CompilerServices {
public class TasklikeAttribute : Attribute {
public TasklikeAttribute(Type builderType) { }
}
}
struct TasklikeTypeMethodBuilder<T> {
public static TasklikeTypeMethodBuilder<T> Create() => throw new NotImplementedException();
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine => throw new NotImplementedException();
public void SetStateMachine(IAsyncStateMachine stateMachine) => throw new NotImplementedException();
public void SetResult(T result) => throw new NotImplementedException();
public void SetException(Exception exception) => throw new NotImplementedException();
public TasklikeType<T> Task => throw new NotImplementedException();
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine => throw new NotImplementedException();
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine => throw new NotImplementedException();
}
[Tasklike(typeof(TasklikeTypeMethodBuilder<>))]
struct TasklikeType<T> { }
static class Program {
static void Main(string[] args) { }
static async TasklikeType<string> TasklikeTypeTester() {
await Task.Yield();
return "hello";
}
}
为 static async TasklikeType<string> TasklikeTypeTester()
.
您无需执行任何其他操作即可启用类任务 returns。这里的问题是此功能的诊断消息尚未更新。这是跟踪问题的 link:
TasklikeAttribute
属性名称原来不是 VS2017 RC 中实现的,而是来自提案的不同版本。实际实现的内容依赖于一种类型 System.Runtime.CompilerServices.AsyncMethodBuilderAttribute
,其工作方式似乎完全相同。
我找不到这个文档,但我能在 Roslyn 测试中找到它,例如 CodeGenAsyncTests.cs:
[AsyncMethodBuilder(typeof(ValueTaskMethodBuilder))] struct ValueTask { } ... namespace System.Runtime.CompilerServices { class AsyncMethodBuilderAttribute : System.Attribute { public AsyncMethodBuilderAttribute(System.Type t) { } } }