4

In C# 6 appears exception filters. So we can write some retry logic as

public static void Retry()
    {
        int i = 3;
        do
        {
            try
            {
                throw new Exception();
            }
            catch (Exception) when (--i < 0)
            {
                throw;
            }
            catch (Exception)
            {
                Thread.Sleep(10);
            }
        } while (true);
    }

In console app it works great. But if we create website app with "optimize code" there will be infinite loop, because value of 'i' never changes. Without "optimize code" this worked as expected. How to test: Create in empty asp.net website application (i try .net 4.5.2 and .net 4.6). add this code to global application class

public class Global : System.Web.HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        int i = 3;
        do
        {
            try
            {
                throw new Exception();
            }
            catch (Exception) when (--i < 0)
            {
                throw;
            }
            catch (Exception)
            {
                Thread.Sleep(10);
            }
        } while (true);
    }
}

Project properties -> Build -> check "optimize code". Run application. Get Infinite loop. Is this right behaivior or it'a bug in compiller?

Upd1: So it's seems very rare condition with unar decrement and rethrowing exception. repeated while compile in VS 2015 on windows 7 (try it on several machines). In VS2015 on windows 10 works fine.
Also it's work if change code like this

int i = 3;
   do
   {
       try
       {
          throw new Exception();
       }
       catch (Exception) when (--i > 0)
       {
          Thread.Sleep(10);
       }
   } while (true);

which will be more suitable in real world example (because unwinded stack)

4
  • 3
    I just tried it in newly created web forms asp.net project in VS 2015 and everything worked as expected. Seems like your specific configuration is affected (or while adopting code for SO you accidently deleted error part). But anyway it is bad idea to use filters in such way. Commented Nov 24, 2015 at 12:15
  • do you try in release configuration? Commented Nov 24, 2015 at 13:07
  • create a test project Commented Nov 24, 2015 at 13:09
  • Yes, works fine in release and debug Commented Nov 24, 2015 at 13:31

2 Answers 2

2

I think that may be a bug. You should report it as such, IMO. Whether it is or not though I wouldn't advise you take this approach.

Firstly, you are side-effecting in your exception filter. That's probably a bad practice generally. Think of it in CQS terms; the filter is a query, not a command.

Secondly, you don't really gain anything. Because you are catching the same exception in the next block, what do you gain from exception-filter behaviour (no stack unwinding if not matched) over just putting the logic into the second catch block? Nothing.

The code:

int i = 3;
do
{
  try
  {
    throw new Exception();
  }
  catch (Exception)
  {
    if (--i < 0)
      throw;
    Thread.Sleep(10);
  }
} while (true);

Expresses idea that you always want to catch the exception, but you want to behave differently in the face of that exception being caught depending on other conditions. This makes it better express the retry concept than an exception filter, which expresses the idea that you only want to catch the exception at all, depending on other conditions.

Sign up to request clarification or add additional context in comments.

1 Comment

Will agree with yor answer, because in most suitable use (see my update) it works.
0

A quick fix. You can move your decrement logic inside catch. And reduce counter by 1.

public static void Retry()
{
    int i = 3 - 1;
    do
    {
        try
        {
            throw new Exception();
        }
        catch (Exception) when (i < 0)
        {
            throw;
        }
        catch (Exception)
        {
            i--;
            Thread.Sleep(10);
        }
    } while (true);
}

Ok. i can say thats a bug now. The tests shows your code works fine in 32bit mode. but not works in 64bit mode.

2 Comments

Yes, we can. But i don't understand why behavior is changing when we "optimize code"
Ok. Not everything works perfect. Even in. Net ;) thats probably a mistake. @OlegAlekseenko

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.