将async方法标记为未实现/不支持或无效操作的正确方法是什么.为了简单,我会用唯一NotImplementedException的例子,但问题适用于NotSupportedException和InvalidOperationException为好.
以同步方式,可以简单地抛出异常:
public override void X() {
throw new NotImplementedException();
}
Run Code Online (Sandbox Code Playgroud)
异步世界中这段代码的等价物是什么?
/* 1 */ public override Task XAsync() {
throw new NotImplementedException();
}
Run Code Online (Sandbox Code Playgroud)
要么
/* 2 */ public override Task XAsync() {
return Task.FromException(new NotImplementedException());
}
Run Code Online (Sandbox Code Playgroud)
这些方法的并发症有哪些?有没有更好的方法?
为了避免"Nah,你不需要一个方法在这里异步"/"它不是异步"我会说该方法实现了一些接口或抽象类.
我不考虑的一些方法:
/* 3 */ public async override Task XAsync() { // here is an CS1998 warning
throw new NotImplementedException();
}
Run Code Online (Sandbox Code Playgroud)
编译器只会生成无用的状态机,它在语义上等效于2
/* 4 */ public async override Task XAsync() {
await Task.Yield();
throw new NotImplementedException();
}
Run Code Online (Sandbox Code Playgroud)
当调用返回 a 的方法时Task,它的某些部分是同步执行的(即使实现方法被定义为async并且其中有await调用......直到第一次离开,默认情况下一切都是同步的)。
因此,所有选项的结果都是相同的:立即抛出或返回一个已完成但有异常的任务(仅当您立即等待调用时行为相同)或标记一个方法async(这会期望您有await调用,但让我们添加为了完整性)。
我会立即抛出,因为返回任务可能表明您“已经开始工作”,并且调用者不需要等待任务,因此如果调用者并不真正关心您何时Task完成(它甚至不关心)有返回值),该方法未实现的事实不会显示出来。