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>
andTask
.
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()
.
There is nothing else you need to do to enable task-like returns. The issue here is that the diagonstic message for this feature hasn't been updated yet. Here is a link to the tracking issue:
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) { } } }
来源:https://stackoverflow.com/questions/41133510/how-do-i-get-the-new-async-semantics-working-in-vs2017-rc