为什么CancellationTokenSource.Cancel导致我的UI锁定几秒钟?

时间:2017-08-08 16:57:26

标签: c# vb.net winforms asynchronous

我正在vb.net上写一个winforms应用程序(尽管C#答案也是可以接受的。)

我正在尝试取消对Await Stream.CopyToAsync()

的通话

请参阅下面的大大简化的代码:

Private _CTS As New Threading.CancellationTokenSource

Private Async Sub DBToFile(ByVal Path As String)
    Dim DBStream as stream = GetDBStream()
    Dim FStream As FileStream = File.Create(Path)
    Await DBstream.CopyToAsync(FStream, 81920, _CTS.Token)
End Sub

当我从用户界面调用_CTS.Cancel()时,会导致它冻结几秒钟。为什么会这样?即使我使用Task.Run(Sub() _CTS.Cancel())来调用它,也没有区别。

如果我将令牌与Await DBstream.CopyToAsync(FStream, 81920, _CTS.Token)的呼叫解耦,(例如只调用Await DBstream.CopyToAsync(FStream)),则不会发生冻结(即使.Cancel()仍然被调用。

对于我所做错的任何建议都会感激不尽。

1 个答案:

答案 0 :(得分:0)

感谢@tinudu的建议,我想我可能已经缩小了它。

似乎冻结发生在调用Await Stream.CopyToAsync()之后,而不是在。{/ p>期间

我没有考虑到这一点,因为在调用Await Stream.CopyToAsync()之后没有发生任何事情, EXCEPT 它包含在多个Using块中,所以有一个有点处置待遇。我只能假设这就是原因。

这也可以解释为什么在单独的任务中调用_CTS.Cancel()没有帮助,因为我假设Await Stream.CopyToAsync()之后的代码继续在原始线程上。