C# 如何让新的异步语义在VSRC中工作?

C# 如何让新的异步语义在VSRC中工作?,c#,async-await,visual-studio-2017,c#-7.0,C#,Async Await,Visual Studio 2017,C# 7.0,引用 语言扩展和分析器 这个版本包括一些我们正在为C#和Visual Basic的下一个版本开发的新语言扩展。默认情况下,将启用这些新语言功能,包括: 对于C#: :这引入了从异步方法返回任何类似任务类型的功能。以前,这些返回类型被限制为Task和Task 它说它是默认启用的,但我无法让它工作。即使从链接的Github页面下载了ArbitraryAsyncReturns.zip(并修复了React NuGet包的引用以删除不相关的错误),但在没有安装定制的VSIX包(用于VS2015)的情况

引用

语言扩展和分析器

这个版本包括一些我们正在为C#和Visual Basic的下一个版本开发的新语言扩展。默认情况下,将启用这些新语言功能,包括:

对于C#:

  • :这引入了从异步方法返回任何类似任务类型的功能。以前,这些返回类型被限制为
    Task
    Task
它说它是默认启用的,但我无法让它工作。即使从链接的Github页面下载了ArbitraryAsyncReturns.zip(并修复了React NuGet包的引用以删除不相关的错误),但在没有安装定制的VSIX包(用于VS2015)的情况下,我仍然可以

错误CS1983:异步方法的返回类型必须为void、Task或Task

我是否需要采取任何额外的步骤来实现这一点


我第一次尝试将这个特定的例子简化为一个应该有效的最小版本,但是尝试使用它,我还不知道什么应该有效,什么不应该有效。但至少,考虑到这种语言增强,我预计会有一个虚假的程序,比如

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";
    }
}
使用系统;
使用System.Runtime.CompilerServices;
使用System.Threading.Tasks;
命名空间System.Runtime.CompilerServices{
公共类TasklikeAttribute:属性{
公共TasklikeAttribute(类型builderType){}
}
}
结构TasklikeTypeMethodBuilder{
公共静态TasklikeTypeMethodBuilder Create()=>抛出新的NotImplementedException();
public void Start(ref TStateMachine stateMachine),其中TStateMachine:IAsyncStateMachine=>throw new NotImplementedException();
public void SetStateMachine(IAsyncStateMachine stateMachine)=>抛出新的NotImplementedException();
public void SetResult(T result)=>抛出新的NotImplementedException();
public void SetException(Exception Exception)=>抛出新的NotImplementedException();
public TasklikeType Task=>抛出新的NotImplementedException();
public void waitingcompleted(ref TAwaiter waitier,ref TStateMachine stateMachine),其中TAwaiter:INotifyCompletion,其中TStateMachine:IAsyncStateMachine=>抛出新的NotImplementedException();
public void AwaitUnsafeOnCompleted(ref TAwaiter waiter,ref TStateMachine stateMachine),其中TAwaiter:ICriticalNotifyCompletion,其中TStateMachine:IAsyncStateMachine=>抛出新的NotImplementedException();
}
[Tasklike(typeof(TasklikeTypeMethodBuilder))]
结构TasklikeType{}
静态类程序{
静态void Main(字符串[]args){}
静态异步TasklikeType taskLikeTypester(){
等待任务;
回复“你好”;
}
}

对于
静态异步TasklikeType taskliketypester()

生成了与上述相同的编译器错误,您无需执行任何其他操作即可启用类似于任务的返回。这里的问题是,此功能的诊断消息尚未更新。以下是跟踪问题的链接:


TasklikeAttribute
属性名称并不是VS2017 RC中实现的名称,而是来自提案的不同版本。实际实现的依赖于类型
System.Runtime.CompilerServices.AsyncMethodBuilderAttribute
,它的工作方式似乎完全相同

我无法找到记录在案的,但我可以在Roslyn测试中找到,例如:


你对任务类型的理解是什么?你读过引用的GitHub问题吗?@PauloMorgado当然。我不认为我的
Test
struct是一种类似于任务的类型。我特别指出,我并不希望代码能够编译,我只是希望错误消息会有所不同,是指类似任务的类型,而不是
task
。我还尝试了Github问题中假定有效的代码,但也未能编译。但是:类任务类型是应用了
Tasklike
属性的类型(可以是用户定义的),其中该属性指定了生成器类型。类型所做的并不是编译器的问题,有些示例很难像任务一样!谢谢你,这回答了一部分问题。不过,我在问题中链接到的假定有效的代码也失败了。当我可以的时候,我会尝试用一个我认为应该有效的最小程序来更新我的问题。好吧,事实证明你是对的,没有什么可以做的来启用类似任务的返回。然而,微软链接到的提案并不是真正得到实施的。。。这是毫无意义的混乱。正如@hvd所说,这回答了其中的一部分,但尽管没有什么可以做的来启用类似于返回的任务,但我甚至无法在VS 2017 RC中找到开箱即用的“ValueTask”,我不知道是否必须下载并安装ArbirtraryAsynReturns.zip和VSIX软件包才能获得它。@SERWare这将是一个.NET Framework添加,而不是编译器添加,因此不能作为VS2017的一部分提供。当您使用该类型时,您会看到红线表示找不到它,VS2017已经告诉您它是Microsoft NuGet软件包的一部分,并提供安装它。@hvd非常感谢您,我今天下班后将在一个以NET Framework 4.6.2为目标的项目中尝试它(我想我只注意到了错误消息,没有注意到红线).
[AsyncMethodBuilder]
远不如
[Tasklike]
漂亮:(
[AsyncMethodBuilder(typeof(ValueTaskMethodBuilder))]
struct ValueTask { }
...
namespace System.Runtime.CompilerServices { class AsyncMethodBuilderAttribute : System.Attribute { public AsyncMethodBuilderAttribute(System.Type t) { } } }