开发者

Yield return from a try/catch block [duplicate]

开发者 https://www.devze.com 2023-03-31 14:37 出处:网络
This question already has answers here: yield return with try catch, how can i solve it (10 answers) Closed 10 years ago.
This question already has answers here: yield return with try catch, how can i solve it (10 answers) Closed 10 years ago.

As Eric Lippert described in this article, yield return is not allowed within try/catch clauses.

Is there a nice way I could get something like this, without having to write my own IEnumerator by hand:

public IEnumerable<Data> GetData()
{
    var transaction 开发者_StackOverflow= Session.BeginTransaction());
    try 
    {
        IQuery q = CreateQuery(session);

        foreach (var result in q.Enumerable())
            yield return ProjectResult(result);  // <-- doesn't work

        session.Commit();
    }
    catch (Exception ex)
    {
        transaction.Rollback();
        throw;
    }
    finally
    {
        transaction.Dispose();
    }
}


I'd just change the transaction-handling logic like this:

public IEnumerable<Data> GetData()
{
    var transaction = Session.BeginTransaction();
    bool rollback = true;
    try 
    {
        IQuery q = CreateQuery(session);

        foreach (var result in q.Enumerable())
        {
            yield return ProjectResult(result);
        }

        rollback = false;
        session.Commit();
    }
    finally
    {
        if (rollback)
        {
            transaction.Rollback();
        }
        transaction.Dispose();
    }
}

Or if your transaction supports the idea of "dispose means rollback unless it's commited":

public IEnumerable<Data> GetData()
{
    using (var transaction = Session.BeginTransaction();
    {
        IQuery q = CreateQuery(session);

        foreach (var result in q.Enumerable())
        {
            yield return ProjectResult(result);
        }

        // Commits the tnrasaction, so disposing it won't roll it back.
        session.Commit();
    }
}


Re-factor

foreach (var result in q.Enumerable()) 
  yield return ProjectResult(result);

into a separate method and simply return it's result.

0

精彩评论

暂无评论...
验证码 换一张
取 消