设置CancellationToken时抛出任意异常是不好的做法吗?

时间:2016-05-31 10:27:16

标签: c# async-await

在检测到myarray = ['3','5','6']; myarray.forEach(function (item){var ind = myarray.indexOf(item); myarray[ind] = parseFloat(item)}); 时,通过抛出OperationCancelledException之外的其他内容,让我的库突破方法是不好的做法吗?

例如:

CancellationToken.IsCancelRequested

取消后,可以根据时间投掷async Task<TcpClient> ConnectAsync(string host, int port, CancellationToken ct) { var client = new TcpClient(); try { using (ct.Register(client.Close, true)) { await client.ConnectAsync(host, port); } // Pick up strugglers here because ct.Register() may have hosed our client ct.ThrowIfCancellationRequested(); } catch (Exception) { client.Close(); throw; } return client; } ObjectDisposedException。 (因为NullReferenceException可以在同时调用TcpClient.ConnectAsync()时抛出其中任何一个。)

现在,我可以修复这样:

TcpClient.Close()

同样适用于调用层次结构的每一层:

async Task<TcpClient> ConnectAsync(string host, int port, CancellationToken ct)
{
    var client = new TcpClient();
    try
    {
        using (ct.Register(client.Close, true))
        {
            try
            {
                await client.ConnectAsync(host, port);
            }
            catch (Exception)
            {
                // These exceptions are likely because we closed the
                // connection with ct.Register().  Convert them to
                // OperationCancelledException if that's the case
                ct.ThrowIfCancellationRequested();
                throw;
            }
        }

        // Pick up strugglers here because ct.Register() may have hosed our client
        ct.ThrowIfCancellationRequested();
    }
    catch (Exception)
    {
        client.Close();
        throw;
    }

    return client;
}

但是,实际上,只需要在最外层进行一次检查,就会增加这些额外的代码。 (在取消来源。)

让这些任意异常飞行是不好的做法?或者在最外面的来电者常规中忽略它们?

1 个答案:

答案 0 :(得分:2)

如果要求取消,您应该抛出OperationCancelledException。当您的代码的消费者获得异常时,他们将不知道它是否实际上是取消或其他。

也就是说,如果由于注册了close委托而无法抛出OperationCancelledException,你可以尝试提供here方法,在那里你将创建一个关闭tcpClient或流的任务并验证任务已完成,并相应采取行动。