如何让新的异步语义在 VS2017 RC 中工作?

How do I get the new async semantics working in VS2017 RC?(如何让新的异步语义在 VS2017 RC 中工作?)
本文介绍了如何让新的异步语义在 VS2017 RC 中工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

引用自 Visual Studio 2017 RC 发行说明

<块引用>

语言扩展和分析器

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

对于 C#:

  • 异步方法的类似任务的返回类型:这引入了返回任何来自异步方法的类似任务的类型.以前,这些返回类型仅限于 Task<T>Task.

它说它默认启用,但我无法让它工作.即使从链接的 Github 页面下载 ArbitraryAsyncReturns.zip (并修复对 React NuGet 包的引用以删除不相关的错误),但没有安装自定义 VSIX 包(适用于 VS2015),我继续得到

<块引用>

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

我是否需要采取任何其他步骤才能使其正常工作?


我首先尝试将该特定示例简化为应该可以工作的最小版本,但是尝试使用它时,我还不知道什么应该工作,什么不应该工作.至少,鉴于这种语言增强,我预计会有一个虚假程序,例如

结构测试{ }静态类程序{静态异步测试测试(){}静态无效 Main() { }}

编译失败并显示不同的错误消息.即使在那时收到相同的错误消息表明此语言扩展尚未启用,但 JaredPar 注意到该错误消息根本尚未更新.


我现在将一个所谓的有效示例缩减为我认为应该编译的最小版本(但由于未实现的方法在运行时失败),但没有编译:

使用系统;使用 System.Runtime.CompilerServices;使用 System.Threading.Tasks;命名空间 System.Runtime.CompilerServices {公共类TasklikeAttribute:属性{公共TasklikeAttribute(类型builderType){}}}struct TasklikeTypeMethodBuilder<T>{公共静态TasklikeTypeMethodBuilder<T>创建()=>抛出新的 NotImplementedException();public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine =>抛出新的 NotImplementedException();公共无效 SetStateMachine(IAsyncStateMachine stateMachine) =>抛出新的 NotImplementedException();公共无效 SetResult(T 结果) =>抛出新的 NotImplementedException();公共无效SetException(异常异常)=>抛出新的 NotImplementedException();public TasklikeType<T>任务=>抛出新的 NotImplementedException();public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine =>抛出新的 NotImplementedException();public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine =>抛出新的 NotImplementedException();}[Tasklike(typeof(TasklikeTypeMethodBuilder<>))]struct TasklikeType<T>{ }静态类程序{静态无效主要(字符串[] args){}静态异步TasklikeType<string>TasklikeTypeTester() {等待 Task.Yield();返回你好";}}

static async TasklikeType 生成与上面相同的编译器错误TasklikeTypeTester().

解决方案

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

我无法找到此文档,但我能够在 Roslyn 测试中找到它,例如 CodeGenAsyncTests.cs:

<块引用>

[AsyncMethodBuilder(typeof(ValueTaskMethodBuilder))]结构值任务 { }...命名空间 System.Runtime.CompilerServices { 类 AsyncMethodBuilderAttribute : System.Attribute { public AsyncMethodBuilderAttribute(System.Type t) { } } }

Quoting from 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.

It says it's enabled by default, but I'm not able to get this to work. Even taking the exact ArbitraryAsyncReturns.zip download from the linked Github page (and fixing up the references to React NuGet packages to remove unrelated errors), but without installing the custom VSIX package (which is for VS2015), I continue to get

error CS1983: The return type of an async method must be void, Task or Task<T>

Do I need to take any additional steps to get this working?


I first tried reducing that specific example to a minimal version that should work, but trying to play with it, I didn't know yet what should work and what shouldn't. At the very least though, given this language enhancement, I expected a bogus program such as

struct Test { }
static class Program {
    static async Test Test() { }
    static void Main() { }
}

to fail to compile with a different error message. Getting the same error message even then suggested that this language extension was not yet enabled, but JaredPar noticed that the error message simply hasn't been updated yet.


I now reduced one of the supposedly valid examples to a minimal version that I think should compile (but fail at run-time due to the unimplemented methods), but doesn't compile:

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";
    }
}

The same compiler error as above is generated for static async TasklikeType<string> TasklikeTypeTester().

解决方案

The TasklikeAttribute attribute name turns out isn't what's implemented in VS2017 RC, that's from a different version of the proposal. What's actually implemented relies on a type System.Runtime.CompilerServices.AsyncMethodBuilderAttribute, which appears to work exactly the same way.

I was not able to find this documented, but I was able to find this in the Roslyn tests, for example CodeGenAsyncTests.cs:

[AsyncMethodBuilder(typeof(ValueTaskMethodBuilder))]
struct ValueTask { }
...
namespace System.Runtime.CompilerServices { class AsyncMethodBuilderAttribute : System.Attribute { public AsyncMethodBuilderAttribute(System.Type t) { } } }

这篇关于如何让新的异步语义在 VS2017 RC 中工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)