在 .NET Standard 上实现异步 return 类型
Implementing async return Types on .NET Standard
大家好,我正在尝试使用 .NetCore 框架的 AsyncMethodBuilderAttribute
创建自己的 Task
-Like 类型。
到目前为止,在 .Net Core
中,我的自定义 Type
有效,它可以是 awaited
并且我可以 return 它作为 async [MyTypeName]<T> MyMethod()
而不是 Task
。
但是在 .NetStandard 2.0
中该属性不存在,我试图实现它:
我用该属性装饰了我的可等待类型,但它仍然不允许我使用它:"The return type of an async method must be void,Task,Task<T>"
到目前为止,我可以在 .Net Core
中使用类似的东西并且它有效!!
public async Task WrapperMethod(){
int result=await GetIntAsync();
}
public async Errand<int> GetIntAsync()
{
await Task.Delay(1000);
return 3;
}
属性:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)]
public sealed class AsyncMethodBuilderAttribute : Attribute {
//
// Parameters:
// builderType:
public AsyncMethodBuilderAttribute(Type builderType) {
this.BuilderType = builderType;
}
//
public Type BuilderType { get; }
}
下面是自定义类型的实现和async method builder
。awaiter
在这种情况下并不重要,但如果需要我可以提供源代码。
我的Task
-喜欢类型
[AsyncMethodBuilder(typeof(Builder))]
public partial class Errand {
private readonly Builder mbuilder;
public Errand() {
}
internal Errand(Builder methodBuilder) => this.mbuilder = methodBuilder;
private readonly HashSet<Awaiter> awaiters = new HashSet<Awaiter>();
protected bool isCompleted = false;
public Awaiter GetAwaiter() {
Awaiter result = new Awaiter(this);
this.awaiters.Add(result);
return result;
}
}
自定义 AsyncMethodBuilder
实现:
public partial class Builder {
#region " Compiler integration "
public static Builder Create() {
return new Builder();
}
protected IAsyncStateMachine myStateMachine;
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine {
this.myStateMachine = stateMachine;
this.errand = new Errand(this);
stateMachine.MoveNext();
}
public void SetException(Exception ex) {
}
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine machine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine {
var foo = machine as IAsyncStateMachine;
awaiter.OnCompleted(() => { foo.MoveNext(); });
}
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine machine)where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine {
IAsyncStateMachine asyncMachine = machine as IAsyncStateMachine;
awaiter.OnCompleted(() => asyncMachine.MoveNext());
}
private Errand errand;
public Errand Task { get { return this.errand; } }
public void SetStateMachine(IAsyncStateMachine stateMachine) {
}
public void SetResult() {
}
#endregion
// internal void AddAwaiter(Awaiter awaiter) => this.awaiters.Add(awaiter);
}
我还应该添加什么才能在 .Net Standard 中工作?
属性的源文件在哪里并不重要,但它确实需要有正确的命名空间声明:
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)]
public sealed class AsyncMethodBuilderAttribute : Attribute
{
public AsyncMethodBuilderAttribute(Type builderType) =>
BuilderType = builderType;
public Type BuilderType { get; }
}
}
大家好,我正在尝试使用 .NetCore 框架的 AsyncMethodBuilderAttribute
创建自己的 Task
-Like 类型。
到目前为止,在 .Net Core
中,我的自定义 Type
有效,它可以是 awaited
并且我可以 return 它作为 async [MyTypeName]<T> MyMethod()
而不是 Task
。
但是在 .NetStandard 2.0
中该属性不存在,我试图实现它:
我用该属性装饰了我的可等待类型,但它仍然不允许我使用它:"The return type of an async method must be void,Task,Task<T>"
到目前为止,我可以在 .Net Core
中使用类似的东西并且它有效!!
public async Task WrapperMethod(){
int result=await GetIntAsync();
}
public async Errand<int> GetIntAsync()
{
await Task.Delay(1000);
return 3;
}
属性:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)]
public sealed class AsyncMethodBuilderAttribute : Attribute {
//
// Parameters:
// builderType:
public AsyncMethodBuilderAttribute(Type builderType) {
this.BuilderType = builderType;
}
//
public Type BuilderType { get; }
}
下面是自定义类型的实现和async method builder
。awaiter
在这种情况下并不重要,但如果需要我可以提供源代码。
我的Task
-喜欢类型
[AsyncMethodBuilder(typeof(Builder))]
public partial class Errand {
private readonly Builder mbuilder;
public Errand() {
}
internal Errand(Builder methodBuilder) => this.mbuilder = methodBuilder;
private readonly HashSet<Awaiter> awaiters = new HashSet<Awaiter>();
protected bool isCompleted = false;
public Awaiter GetAwaiter() {
Awaiter result = new Awaiter(this);
this.awaiters.Add(result);
return result;
}
}
自定义 AsyncMethodBuilder
实现:
public partial class Builder {
#region " Compiler integration "
public static Builder Create() {
return new Builder();
}
protected IAsyncStateMachine myStateMachine;
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine {
this.myStateMachine = stateMachine;
this.errand = new Errand(this);
stateMachine.MoveNext();
}
public void SetException(Exception ex) {
}
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine machine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine {
var foo = machine as IAsyncStateMachine;
awaiter.OnCompleted(() => { foo.MoveNext(); });
}
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine machine)where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine {
IAsyncStateMachine asyncMachine = machine as IAsyncStateMachine;
awaiter.OnCompleted(() => asyncMachine.MoveNext());
}
private Errand errand;
public Errand Task { get { return this.errand; } }
public void SetStateMachine(IAsyncStateMachine stateMachine) {
}
public void SetResult() {
}
#endregion
// internal void AddAwaiter(Awaiter awaiter) => this.awaiters.Add(awaiter);
}
我还应该添加什么才能在 .Net Standard 中工作?
属性的源文件在哪里并不重要,但它确实需要有正确的命名空间声明:
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)]
public sealed class AsyncMethodBuilderAttribute : Attribute
{
public AsyncMethodBuilderAttribute(Type builderType) =>
BuilderType = builderType;
public Type BuilderType { get; }
}
}