简体   繁体   中英

Exception not thrown in an async Task configuration

I have the following method

    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;
            }
        }
    }

Now, I would expect consecutive calls to Connect() to throw an IOException, but it doesn't happen!

What could be the cause?

Calls to Connect() can't throw exceptions directly. Async methods do not throw exceptions. Instead, they will return tasks which, when awaited, will throw IOException . (ie the tasks are faulted.)

If that's not what you want, you should separate the calls:

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;
        }
    }
}

It's not clear whether that's appropriate in this case though. It's generally fine to throw things like ArgumentException eagerly, but if the error doesn't represent a bug in the calling code itself, I think returning a faulted task instead is fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM