出于好奇,我试图在.NET 3.5 Client Profile下编译一些简单的async
/ await
代码:
async void AwaitFoo()
{
await new Foo();
}
class Foo
{
public IFooAwaiter GetAwaiter() { … }
}
interface IFooAwaiter : System.Runtime.CompilerServices.INotifyCompletion
{
bool IsCompleted { get; }
void GetResult();
}
我完全清楚.NET 3.5不支持此语言功能,如此编译错误所表达的那样:
无法找到
async
修饰符所需的所有类型。您是否定位错误的框架版本,或缺少对程序集的引用?
我也知道NuGet package Microsoft.Bcl.Async
,它不支持.NET 3.5。
问题 什么是最小类型&输入async
代码编译所需的成员?这个最小集是否正式记录;如果是的话,在哪里? (请注意,我只对成功编译感兴趣,而不是执行。)
到目前为止我得到了什么:
我一直试图通过实验找到这个最小的类型集,这似乎是可能的,因为编译器需要报告,但是逐个丢失类型:
未定义或导入预定义类型
System.Runtime.CompilerServices.IAsyncStateMachine
。
根据MSDN参考页面定义报告的类型,然后导致报告下一个丢失的类型。我到目前为止:
System.Runtime.CompilerServices.IAsyncStateMachine
System.Runtime.CompilerServices.INotifyCompletion
(上述示例代码要求)System.Threading.Tasks.CancellationToken
(Task
要求)System.Threading.Tasks.TaskCreationOptions
(Task
要求)System.Threading.Tasks.Task
此时我停了下来,因为Task
有很多成员,但编译器并没有准确报告它需要哪些成员;它只是报告整体类型。因此,我可能会重现比实际需要更多的类型定义。
答案 0 :(得分:8)
就C#编译器而言,您还需要:
AsyncTaskMethodBuilder
AsyncTaskMethodBuilder<TResult>
AsyncVoidMethodBuilder
AsyncStateMachineAttribute
ICriticalNotifyCompletion
虽然我相信'刚刚被建筑商使用。我不会期望实际上需要TaskCreationOptions
或CancellationToken
- 我无法想到它们会在生成的代码中用于何处。< / p>
从根本上说,你真的需要整个TPL支持才能工作 - 只需要编译就不会为你做这件事。如果你只是为了好奇而对此感兴趣,那就是另一回事了。您可能对我的Eduasync博客系列感兴趣,这是一个粗略的版本,让编译器的CTP版本在没有AsyncCtpLibrary.dll
程序集(针对.NET 4.0)的情况下工作 - 基本上提供所有相关类型
source code对C#5编译器不起作用,因为最终版本的内容发生了一些变化,但大多数概念保持不变。
答案 1 :(得分:2)
我已经通过实验确定以下类型足以使C#5编译器处理基本的async
/ await
代码(即使面向.NET Framework版本2!): / p>
IAsyncStateMachine
INotifyCompletion
(不需要会员声明)ICriticalNotifyCompletion
(不需要会员声明)AsyncVoidMethodBuilder
AsyncTaskMethodBuilder
AsyncTaskMethodBuilder<TResult>
Task
(不需要会员声明)Task<TResult>
(不需要会员声明)我发现C#编译器可以接受的最小的声明如下所示。
namespace System.Threading.Tasks
{
abstract class Task { }
abstract class Task<TResult> : Task { }
}
namespace System.Runtime.CompilerServices
{
interface INotifyCompletion { }
interface ICriticalNotifyCompletion { }
interface IAsyncStateMachine
{
void MoveNext();
void SetStateMachine(IAsyncStateMachine stateMachine);
}
struct AsyncVoidMethodBuilder
{
public static AsyncVoidMethodBuilder Create() { … }
public void Start<TStateMachine>(ref TStateMachine stateMachine)
// where TStateMachine : IAsyncStateMachine
{ … }
public void SetResult() { … }
public void SetException(Exception exception) { … }
public void SetStateMachine(IAsyncStateMachine stateMachine) { … }
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
// where TAwaiter : INotifyCompletion
// where TStateMachine : IAsyncStateMachine
{ … }
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
// where TAwaiter : ICriticalNotifyCompletion
// where TStateMachine : IAsyncStateMachine
{ … }
}
struct AsyncTaskMethodBuilder
{
public Task Task { get { … } }
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
// where TAwaiter : INotifyCompletion
// where TStateMachine : IAsyncStateMachine
{ … }
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
// where TAwaiter : ICriticalNotifyCompletion
// where TStateMachine : IAsyncStateMachine
{ … }
public static AsyncTaskMethodBuilder Create() { … }
public void SetException(Exception exception) { … }
public void SetResult() { … }
public void SetStateMachine(IAsyncStateMachine stateMachine) { … }
public void Start<TStateMachine>(ref TStateMachine stateMachine)
// where TStateMachine : IAsyncStateMachine
{ … }
}
struct AsyncTaskMethodBuilder<TResult>
{
public static AsyncTaskMethodBuilder<TResult> Create() { … }
public void Start<TStateMachine>(ref TStateMachine stateMachine)
// where TStateMachine : IAsyncStateMachine
{ … }
public void SetResult(TResult result) { … }
public void SetException(Exception exception) { … }
public void SetStateMachine(IAsyncStateMachine stateMachine) { … }
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
// where TAwaiter : INotifyCompletion
// where TStateMachine : IAsyncStateMachine
{ … }
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
// where TAwaiter : ICriticalNotifyCompletion
// where TStateMachine : IAsyncStateMachine
{ … }
public Task<TResult> Task { get { … } }
}
}
(我在NotImplementedException
所说的任何地方抛出{ … }
。)