Looking for an elegant way to get around "I can’t wait in the body of the final offer,"

I have the following function:

private async Task DoSomething(NamespaceConnectionInfo nci)
{
    var session = await m_sessionProvider.GetSessionAsync(nci);
    SomeLegacySynchronousCode(session);
    await m_sessionProvider.EndSessionAsync(session);
}

where it EndSessionAsyncregisters and swallows any exception (for example, a good destructor).

The problem is that it SomeLegacySynchronousCodecan throw an exception and then the session leaks.

I understand completely why the following code is illegal:

private async Task DoSomething(NamespaceConnectionInfo nci)
{
    var session = await m_sessionProvider.GetSessionAsync(nci);
    try
    {
        SomeLegacySynchronousCode(session);
    }
    finally
    {
        await m_sessionProvider.EndSessionAsync(session);
    }
}

So, I'm looking for an alternative that is right and elegant.

Option I

private async Task DoSomething(NamespaceConnectionInfo nci)
{
    var session = await m_sessionProvider.GetSessionAsync(nci);
    Exception exc = null;
    try
    {
        SomeLegacySynchronousCode(session);
    }
    catch (Exception e)
    {
        exc = e;
    }
    await m_sessionProvider.EndSessionAsync(session);
    if (exc != null)
    {
        // Wrap to preserve the original stack trace.
        throw new AggregateException(exc);
    }
}

Option II

private Task DoSomething(NamespaceConnectionInfo nci)
{
    return m_sessionProvider.GetSessionAsync(nci).ContinueWith(t =>
    {
        Task result = null;
        try
        {
            SomeLegacySynchronousCode(t.Result);
        }
        finally
        {
            if (t.Exception == null)
            {
                result = m_sessionProvider.EndSessionAsync(t.Result);
            }
        }
        return result;
    }).Unwrap();
}

Not as elegant as the aforementioned illegal version of async / await.

I want to improve the two options I have proposed, because they are both ugly, to be honest.

Any ideas?

+4
source share
1 answer

, , 1:

catch , , ExceptionDispatchInfo.

static async Task f()
{
    ExceptionDispatchInfo capturedException = null;
    try
    {
        await TaskThatFails();
    }
    catch (MyException ex)
    {
        capturedException = ExceptionDispatchInfo.Capture(ex);
    }

    if (capturedException != null)
    {
        await ExceptionHandler();

        capturedException.Throw();
    }
}

, StackTrace , - , TaskThatFails .

+4

Source: https://habr.com/ru/post/1531652/


All Articles