在异步任务配置中未抛出的异常

本文关键字:异常 异步 任务 配置 | 更新日期: 2023-09-27 18:07:40

我有以下方法

    public async Task<bool> Connect()
    {
        lock (_connectingLock)
        {
            if (_connecting)
                throw new IOException("Already connecting");
            _connecting = true;
        }
        try {
             await tcpClient.ConnectAsync(...); 
        }           
        catch (SocketException e)
        {
            return false;
        }
        finally
        {
            lock (_connectingLock)
            {
                _connecting = false;
            }
        }
    }

现在,我希望连续调用Connect()抛出IOException,但它不会发生!

原因是什么?

在异步任务配置中未抛出的异常

调用Connect()不能直接抛出异常。异步方法不会抛出异常。相反,它们将返回等待时抛出IOException的任务。(即任务失败)

如果这不是你想要的,你应该分开调用:

public Task<bool> Connect()
{
    // Eager validation of state...
    lock (_connectingLock)
    {
        if (_connecting)
            throw new IOException("Already connecting");
        _connecting = true;
    }
    return ConnectImpl();
}
private async Task<bool> ConnectImpl()
{
    try {
         await tcpClient.ConnectAsync(...); 
    }           
    catch (SocketException e)
    {
        return false;
    }
    finally
    {
        lock (_connectingLock)
        {
            _connecting = false;
        }
    }
}

目前尚不清楚在这种情况下是否合适。急切地抛出像ArgumentException这样的东西通常是好的,但是如果错误不代表调用代码本身的错误,我认为返回一个错误的任务是好的。