CreateLinkedTokenSource

CreateLinkedTokenSource

之前在这里已经问过多个类似的问题。

MSDN声明one should always dispose the CancellationTokenSource when done with it为重要提示。

可以,但是使用多线程应用程序和异步等待模型会变得有些复杂。

我正在开发图书馆。我遇到的问题是,我在从用户收到的CreateLinkedTokenSource中使用CancellationToken的几个地方。很快,我正在这样做,以便我可以取消自己的操作(如果它花费的时间超过了一段时间)。

例子

public async Task<Result> DoAsync(CancellationToken cancellationToken)
{
    using (var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
    {
        // here pass linkedTokenSource.Token further down the line
        var resultTask = sender.DoAsync(linkedTokenSource.Token);
        var timeoutTask = Task.Delay(timeout);
        var completed = await Task.WhenAny(resultTask, timeoutTask);
        if (completed  == timeoutTask)
        {
            linkedTokenSource.Cancel();
            throw TimeoutException();
        }

        return await resultTask;
        // from the point of view of this piece of code
        // we're done with the cancellationTokenSource right?
        // so I need to dispose the source (done here via `using`)
    }
}

但是,由于竞争条件的缘故,在不同代码段中,由于某些线程正在尝试从CreateLinkedTokenSource中删除linkedTokenSource.Token,从而导致生成ObjectDisposedException,因为在抛出linkedTokenSource之后已经处理掉了TimeoutException
这将以UnobservedTaskException结尾,如果用户监听未观察到的异常,将会使用户感到困惑。

对我来说,在每个try-catch上放一个CreateLinkedTokenSource并使ObjectDisposedException行静音似乎又很奇怪。

我的问题是:
  • 为什么CreateLinkedTokenSource抛出此异常?请问对此有解释吗?由于CencellationToken是一个结构,为什么我不能从中创建新的源代码? (甚至在cancelToken中也被取消)。
  • 关于在这种情况下应如何处理的任何建议?
  • 最佳答案



    好吧,有点。每当您使用UnobservedTaskException时,Task.WhenAny几乎总是生活中的事实(并且放弃不完整的任务,这是Task.WhenAny使用的绝大部分时间)。

    因此,他们可能会收到报告给ObjectDisposedExceptionUnobservedTaskException而不是OperationCanceledException的信息。 h在async世界中,如果您使用的是Task.WhenAny,则无论如何,您确实确实需要忽略UnobservedTaskException。此外,许多“不容易取消”的端点将在取消请求时关闭底层句柄,这无论如何都会导致(IIRC)ObjectDisposedException



    它是这些really, really old Microsoft design guidelines that were written with an '80s OOP mindset的一部分。我从未同意MS的Dispose指南,而是希望使用much simpler model来涵盖所有相同的用例,而所需的精神开销却大大减少。



    保持原样。 UnobservedTaskException没什么大不了的。

    关于c# - CreateLinkedTokenSource引发ObjectDisposedException。如何正确安全地配置CancellationTokenSource?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37441215/

    10-09 14:31