【问题标题】:How do I get the new async semantics working in VS2017 RC?如何让新的异步语义在 VS2017 RC 中工作?
【发布时间】:2017-04-29 05:55:09
【问题描述】:

引用Visual Studio 2017 RC Release Notes

语言扩展和分析器

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

对于 C#:

它说它默认启用,但我无法让它工作。即使从链接的 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";
    }
}

static async TasklikeType&lt;string&gt; TasklikeTypeTester() 生成与上述相同的编译器错误。

【问题讨论】:

  • 您对Task-like type的理解是什么?你读过引用的 GitHub 问题吗?
  • @PauloMorgado 当然。我不认为我的 Test 结构是类似任务的类型。我特别指出我没想到代码会编译,我只是希望错误消息有所不同,指的是类似任务的类型而不是Task。我还尝试了 Github 问题中所谓的有效代码来自,它也无法编译。但是:类似任务的类型是应用了Tasklike 属性的类型(可能是用户定义的),其中该属性指定了构建器类型。类型的作用实际上并不是编译器的问题,而且有些示例几乎不像任务。

标签: c# async-await visual-studio-2017 c#-7.0


【解决方案1】:

您无需执行任何其他操作即可启用类似任务的返回。这里的问题是此功能的诊断消息尚未更新。这是跟踪问题的链接:

https://github.com/dotnet/roslyn/issues/12621

【讨论】:

  • 哦!谢谢你,这回答了它的一部分。我在我的问题中链接到的所谓有效代码也失败了。如果可以,我会尝试使用我认为应该有效的最小程序来更新我的问题。
  • 好吧,事实证明你是对的,没有什么可做的来启用类似任务的返回。但是,MS 链接到的提案并不完全是实施的……这毫无意义的混乱。
  • 正如@hvd 所说,这回答了其中的一部分,但是虽然没有什么办法可以启用类似任务的回报,但我什至无法在 VS 2017 RC 中找到开箱即用的“ValueTask” ,我不知道是否必须下载并安装 ArbirtraryAsynReturns.zip 和 VSIX 包才能获得它。
  • @SERWare 这将是 .NET Framework 添加,而不是编译器添加,因此不能作为 VS2017 的一部分提供。当您使用该类型时,您会看到红线指示它无法找到,VS2017 已经告诉您它是 Microsoft 的System.Threading.Tasks.Extensions NuGet 包的一部分并提供安装它。
  • @hvd 非常感谢,我今天下班后在一个针对 NET Framework 4.6.2 的项目中尝试一下(我想我只注意到错误消息,没有注意到红线)。
【解决方案2】:

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) { } } }

【讨论】:

  • [AsyncMethodBuilder] 远不如[Tasklike] 漂亮:(
猜你喜欢
  • 2018-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-02
  • 2021-07-19
  • 1970-01-01
  • 1970-01-01
  • 2017-02-08
相关资源
最近更新 更多