将async方法标记为未实现/不支持或无效操作的正确方法是什么。为简单起见,我在示例中仅使用NotImplementedException
,但此问题也适用于NotSupportedException
和InvalidOperationException
。
以同步方式,可以简单地抛出异常:
public override void X() {
throw new NotImplementedException();
}
在异步世界中,这段代码的等价物是什么?
/* 1 */ public override Task XAsync() {
throw new NotImplementedException();
}
或
/* 2 */ public override Task XAsync() {
return Task.FromException(new NotImplementedException());
}
这些方法的并发症有哪些?有没有更好的方法?
为了避免“Nah,你不需要一个方法在这里异步”/“它不是异步”我会说该方法实现了一些接口或抽象类。
我不考虑的一些方法:
/* 3 */ public async override Task XAsync() { // here is an CS1998 warning
throw new NotImplementedException();
}
编译器would just generate the useless state machine,在语义上等同于2
/* 4 */ public async override Task XAsync() {
await Task.Yield();
throw new NotImplementedException();
}
这是the same为3,但是在Task.Yeild()上添加等待;
答案 0 :(得分:5)
我要站出来说“没关系。”
Boneheaded exceptions可以直接抛出(throw
)或放在返回的任务(Task.FromException
)上。由于它们是愚蠢的例外,它们不应该被捕获,所以抛出它们并不重要。
答案 1 :(得分:3)
当调用返回FlxG.worldBounds.set(?X:Float = 0, ?Y:Float = 0, ?Width:Float = 0, ?Height:Float = 0)
的方法时,它的某些部分会同步执行(即使实现方法定义为Task
并且其中有async
个调用..直到第一个离开,默认情况下一切都是同步的。
因此所有选项的结果都是相同的:立即抛出或返回已经完成但带有异常的任务(如果等待立即调用,则行为相同)或标记方法await
(这将是希望您有async
个电话,但我们会将其添加为完整性。
我会立即投掷,因为返回任务可能表示您已经开始工作了#34;并且来电者不需要等待任务,所以如果来电者并不真正关心你的await
何时完成(它甚至没有返回值),该方法未实现的事实不会出现。
答案 2 :(得分:2)
在你的评论中,你写道:
我们正在尝试制作NHibernate的异步版本:)
这让你处于一个不幸的位置:熟练的程序员编写的知名图书馆应该写得好,以防止不太熟练的程序员意外误用(包括通过复制/粘贴滥用)。
有足够多的人希望await Task.WhenAll(a(), b(), c())
之类的代码能够工作,即使其中一个异步操作失败,我也说你的第一个选项甚至不应该是一个选项。如果b()
同步抛出异常,则忽略a()
返回的任务,并且不会调用c()
。
我同意Stephen Cleary的回答说NotImplementedException
正如他所说的那样,是一个无关紧要的愚蠢例外,因为它无论如何都不应该以生产代码结束。但是,你写道:
此问题也适用于
NotSupportedException
和InvalidOperationException
。
这些不一定是愚蠢的例外。这些可能最终出现在生产代码中。
您的第二个选择可以避免这个问题。
您的第二个选项确实存在其他问题:它不会引发异常。由于实际上没有抛出任何异常,因此阻碍了调试:当出现问题时,让调试器中的选项在抛出而不是的位置处断开是非常有用的EM>捕获
我建议也考虑
public async override Task XAsync() {
throw new NotImplementedException();
}
由于与创建状态机相关的开销而丢弃的。我认为这不是丢弃它的正当理由。这是性能不相关的代码,这是仅处理错误情况的代码。我建议它,因为一般来说,我赞成使用async
/ await
直接操作任务,因为它更容易捕获愚蠢的错误,因为开发时间节省的时间足够高值得。
我明白为什么你不想选择这个选项,但我个人仍然愿意。它避免了您的第一个选择的缺点。它避免了第二种选择的缺点。它本身的缺点,即性能稍慢,在我看来不太可能成为问题,而不是其他两个。
在其他两个中,希望这些缺点的细节可以帮助您做出明智的决定。