Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 异步/等待取消机制_C#_Async Await - Fatal编程技术网

C# 异步/等待取消机制

C# 异步/等待取消机制,c#,async-await,C#,Async Await,我有一个问题,可以使用什么机制来取消正在进行的异步操作,而不是异步/等待上下文中的取消令牌。我相信这是一个经过充分研究的设计决策,考虑到了语言的命令性质,但在实际情况下,必须将取消对象传递给所有异步方法至少有点痛苦。c#community还有另一个设计理念,或者提议的取消机制还可以?我想我遗漏了一些东西。取消令牌是最佳实践,特别是当异步进程代价高昂、没有预设的结束条件或涉及外部资源时 然而,如果你愿意,你可以简单地“放弃”。不要告诉异步线程中止处理和清理,只需“超时”;停止等待它完成,分离所有侦

我有一个问题,可以使用什么机制来取消正在进行的异步操作,而不是异步/等待上下文中的取消令牌。我相信这是一个经过充分研究的设计决策,考虑到了语言的命令性质,但在实际情况下,必须将取消对象传递给所有异步方法至少有点痛苦。c#community还有另一个设计理念,或者提议的取消机制还可以?我想我遗漏了一些东西。

取消令牌是最佳实践,特别是当异步进程代价高昂、没有预设的结束条件或涉及外部资源时

然而,如果你愿意,你可以简单地“放弃”。不要告诉异步线程中止处理和清理,只需“超时”;停止等待它完成,分离所有侦听器,并继续运行。当线程最终完成时,它将检查它的事件,意识到没有人在侦听,然后静默终止。优点是简单,但在许多情况下,这将是一件坏事:

  • 如果异步进程将永远保持处理,除非您告诉它停止,它将在后台继续运行,占用CPU和其他资源,直到应用程序关闭,此时线程将被终止
  • 如果异步线程正在执行一个可中止的、可逆的工作单元,如DB操作,如果用户按下cancel,他们希望到目前为止所做的任何事情都已回滚。如果你停止倾听,继续前进,他们会得到的是他们认为他们取消了的表演
  • 在大多数情况下,异步操作涉及需要时间处理的外部资源,并且还需要适当的清理。必须断开网络套接字、关闭数据库连接、解锁文件等。尽管放弃意味着您不必处理这些问题,而是让线程正常结束,但常见的用户体验是用户厌倦了,点击“取消”,然后重试该操作。这意味着您在上一个异步操作中使用的资源必须释放才能再次使用

为了使异步操作的取消变得有意义,该操作必须执行谨慎的步骤,因为检查取消令牌并停止自身继续的操作是由操作决定的。即,取消令牌只是要实现的模式,而不是异步/等待机制

这意味着,如果您的异步操作只是一个带有完成句柄的I/O调用,那么您也可以放弃而不是取消,因为在该调用返回之前,该操作将没有机会检查您的令牌,在该调用返回时,将无法获得任何结果


当考虑取消令牌时,首先考虑是否可以通过支持取消或是否不等待它完成(即使用超时机制)更有效率地执行此操作。包括在异步上的C#5 CTP中。它不是叫C#5,但我在这里用它来表示C#的“下一个”版本。只是注意到你的问题中使用了“等待”,所以你熟悉CTP。我认为任务并行库(.NET 4)某种程度上确认了它提供的功能是可行的,因此异步CTP使用了相同的范例。相关:@Henk Holterman:您提到的相关问题已经解决了。因此,我以一种更友好的方式写下了这个问题。只关注我认为更重要的一点。这个问题与C#5 vNext有关。