Denis
Denis

Reputation: 151

Cannot jump out of the finally block

I'm trying to return a value from a function. The function WcfProvider.MetalsPrices may throw an exception. I want to avoid it.

public IEnumerable<PriceOfMetal> GetPrice(int id, DateTime time)
{
        bool condition = false;
        DateTime timenew = time.AddDays(-1);

        var allPrice = from c in db.PriceOfMetal
                       select c;

        foreach (var i in allPrice)
        {
            if (i.Date.Date == timenew.Date && i.ListOfMetaL_Id==id)
            {
                condition = true;
            }
        }

        try
        {
            if (condition == false)
            {
                var price = WcfProvider.MetalsPrices(id, time, time).Tables[0].AsEnumerable()
                    .Select(
                        a =>
                            new PriceOfMetal()
                            {
                                Date = a.Field<DateTime>("Date"),
                                ListOfMetaL_Id = a.Field<int>("MetalId"),
                                Value = a.Field<System.Double>("Price")
                            })
                    .ToList().Single();

                db.PriceOfMetal.Add(price);
                db.SaveChanges();
            }
        }
        finally 
        {
            var all = from c in db.PriceOfMetal select c;
            return all;
        }

I want to return the value of the block finally. Is it possible? I get an error.

Upvotes: 2

Views: 3357

Answers (3)

Onots
Onots

Reputation: 2118

I'm sorry to say this but your question is vague and hard to answer. Your code looks over complicated. Anyway it's holiday time. Maybe below will help you along. No guarantees though.

public IEnumerable<PriceOfMetal> GetPrice(int id, DateTime time)
{
    DateTime timenew = time.AddDays(-1);

    var allPrice = from c in db.PriceOfMetal
                   select c;
                   where c.Date.Date == timenew.Date
                   and c.ListOfMetal_Id == id

    if (!allPrice.Any())
    {
        try
        {
            var price = WcfProvider.MetalsPrices(id, time, time).Tables[0].AsEnumerable()
                        .Select(a =>new PriceOfMetal
                        {
                            Date = a.Field<DateTime>("Date"),
                            ListOfMetaL_Id = a.Field<int>("MetalId"),
                            Value = a.Field<System.Double>("Price")
                        })
                        .ToList().Single();

            db.PriceOfMetal.Add(price);
            db.SaveChanges();
        }
        catch
        {
            // Eating exceptions like this is really poor. You should improve the design.
        }
    }
    return db.PriceOfMetal;
}  

Upvotes: 0

TheGeneral
TheGeneral

Reputation: 81483

you may need a pattern like this

try
{
   return here
}
catch(Exception ex)
{
   // Catch any error
   // re throw if you choose, 
   // or you can return if you choose
   return here
}
finally
{
  // allways do whats here
}

You might want to read a couple of the pages around here : try-catch-finally (C# Reference)


Just to build on this a bit more, Imagine if we could return within a finally block

You could have a nasty piece of code like below, which would be confusing at best

try
{
    return 10;
}
catch (Exception e)
{
    return 20;
}
finally
{
    return 30;
}

What would the compiler return?

Upvotes: 4

Ben Voigt
Ben Voigt

Reputation: 283624

You have to decide whether your function should return normally or abnormally if an exception occurs inside.

If abnormally (your caller will see the exception):

try {
    // do stuff
    return answer;
}
finally {
    // cleanup stuff
}

If normally, you need to handle the exception:

try {
    // do stuff
}
catch {
    // recover stuff        
}
// cleanup stuff
return answer;

You can never put a return statement in a finally block, because finally runs when there is an uncaught exception, and when your function ends (abnormally) due to uncaught exception, there is no return value.

Upvotes: 7

Related Questions