471,337 Members | 888 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,337 software developers and data experts.

A common architectural problem

Hi,

Assuming having a method that calls another method which also calls other methods and so on having a long winded tree of methods. What do I do in case it turns out everything has to be aborted? The only reasonable way I see here is to use a exception but everybody is telling exceptions should not be used for control flow. I just can't think of another reasonable way to deal with this.

Are there any good books that teach how to do great architecture?

thanks in advance
Frank
Jan 22 '06 #1
11 1665
Hello stax,

This is definatly a debated issue. A rule of thumb though. Exceptions are
Exceptions. They should really only be used for unexpected cases, like invalid
input to a method or some infrstructure bits not clicking (like opening databse
connections etc). Throwing exceptions is a bit expensive and minimizing thrown
exceptions will affect your performance positivly.

For success/failure indication you should use return values.

--
Patrik Löwendahl [C# MVP]
http://www.lowendahl.net
http://www.cornerstone.se

Hi,

Assuming having a method that calls another method which also calls
other methods and so on having a long winded tree of methods. What do
I do in case it turns out everything has to be aborted? The only
reasonable way I see here is to use a exception but everybody is
telling exceptions should not be used for control flow. I just can't
think of another reasonable way to deal with this.

Are there any good books that teach how to do great architecture?

thanks in advance
Frank

Jan 22 '06 #2
I don't know how you scenario looks like, but maybe the class
System.Transactions.TransactionScope and
System.Transactions.DependentTransaction would be of a good use to you in
case you need to rollback. This class is new to .NET 2.0.

"stax" <_r************************@yahoo.de> wrote in message
news:dq**********@online.de...
Hi,

Assuming having a method that calls another method which also calls other
methods and so on having a long winded tree of methods. What do I do in
case it turns out everything has to be aborted? The only reasonable way I
see here is to use a exception but everybody is telling exceptions should
not be used for control flow. I just can't think of another reasonable way
to deal with this.

Are there any good books that teach how to do great architecture?

thanks in advance
Frank

Jan 22 '06 #3
> For success/failure indication you should use return values.

I searched quite a bit but didn't find something so maybe you or somebody else can point me to some resources. The problem with return values is it adds a lot boilerplate code as the return value has to be checked for every method call. My application has a really long winded processing going on. Problems with this approach are often I want to return some types instead of a boolean return value and I'm not very comfortable with global variables or ref parameters.
Jan 22 '06 #4
Patrik Löwendahl [C# MVP] <pa**************@home.se> wrote:
This is definatly a debated issue. A rule of thumb though. Exceptions are
Exceptions. They should really only be used for unexpected cases, like invalid
input to a method or some infrstructure bits not clicking (like opening databse
connections etc). Throwing exceptions is a bit expensive and minimizing thrown
exceptions will affect your performance positivly.
Very few applications will actually see any significant performance
degredation due to using exceptions unless they're thrown hundreds of
thousands of times a second (in which case chances are something more
serious is wrong anyway).

See http://www.pobox.com/~skeet/csharp/exceptions.html for more
empirical data on this.
For success/failure indication you should use return values.


No. If a method has failed, it should throw an exception. Return values
are meant to be used (IMO) for the result of the operation of the
method, not whether or not the method has succeeded in doing what it's
been told to do.

The whole "don't use exceptions for control flow" is very wishy-washy -
it doesn't describe what "control flow" really means, and as exceptions
pretty much *always* affect control flow, it's hard to know what is
actually intended.

There are times when it can be tricky to decide whether or not to use
an exception, but in this case (where a large operation needs to be
aborted) an exception sounds just the ticket to me.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 22 '06 #5
That really depends on the context.

In your example you're doing nothing else then throwing exceptions in a console
application and, as you yourself state, only at one level deep.

Using a different scenario,

Create an ASP.NET application and let it throw a couple of exceptions around
the call stack. Put a thousand or so worth of user load on the app with ACT
and measure throughput. Then get rid of the exception and do another measure.
You will see a significant increase in the throughput for the application
with less exceptions.

Regardless of the performance issue, there's a semantic and architectural
issue to consider as well.

Exceptions are errors, problems with your code that you couldn't anticipate
writing it. Consider the register user scenario.

1) A user registers for a website.
2) A users login name must be unique.

Implementing this what would be the better way? Trying to persist the user
and throw an exception if it fails or anticipate the problem in advance by
checking the input values and send feedback directly?

I would do this:

public enum RegisterStatus { Ok, LoginNameExists };

public RegisterStatus RegisterUser(User newUser) {
bool loginExists = UserRepository.CheckLoginExists(newUser.LoginName) ;

if ( !loginExists ) {
UserRepository.Register(newUser);
return RegisterStatus.Ok;
}
else {
return Register.LoginNameExists;
}
}

Which IMO is a much clearer. Since we expect users to enter login names that
are already used, that is not an Exceptional case and not really an error
on the users behalf, he couldn't know.

Now in another scenario:

1) We want a email class that are supposed to send emails.
2) When sending an email we expect a correct email address to be given to
us and a message to send.

Now here's a place where exceptions do come in. We expect an email adress
to our function, if we don't get it, an exception should be thrown. In this
case it's all about giving the function enough and correct information to
be able to do its job.

public void SendEmail(string to, string from, string subject, string message)
{
if ( !Validator.IsValidateEmail(to) )
throw new ArgumentException("Not a valid email", "to");

if ( !Validator.AreNotEmptyOrNullString(messsage) )
throw new ArgumentException("I need an email text to send", "message");

// Etc....
}

In this case the user are required to know how an emailadress is written,
we expect a user of an email class to know this. Therefore, not getting a
valid email adress is an Exceptional case.

For some more information about exceptions and performance / scalability,
have a browse over at: http://msdn.microsoft.com/library/de...netchapt05.asp
--
Patrik Löwendahl [C# MVP]
http://www.lowendahl.net
http://www.cornerstone.se

Patrik Löwendahl [C# MVP] <pa**************@home.se> wrote:
This is definatly a debated issue. A rule of thumb though. Exceptions
are

Exceptions. They should really only be used for unexpected cases,
like in

valid
input to a method or some infrstructure bits not clicking (like
opening d

atabse
connections etc). Throwing exceptions is a bit expensive and
minimizing t

hrown
exceptions will affect your performance positivly.

Very few applications will actually see any significant performance
degredation due to using exceptions unless they're thrown hundreds of
thousands of times a second (in which case chances are something more
serious is wrong anyway).

See http://www.pobox.com/~skeet/csharp/exceptions.html for more
empirical data on this.
For success/failure indication you should use return values.

No. If a method has failed, it should throw an exception. Return
values are meant to be used (IMO) for the result of the operation of
the method, not whether or not the method has succeeded in doing what
it's been told to do.

The whole "don't use exceptions for control flow" is very wishy-washy
- it doesn't describe what "control flow" really means, and as
exceptions pretty much *always* affect control flow, it's hard to know
what is actually intended.

There are times when it can be tricky to decide whether or not to use
an exception, but in this case (where a large operation needs to be
aborted) an exception sounds just the ticket to me.

Jan 22 '06 #6
Patrik Löwendahl [C# MVP] <pa**************@n0spam.home.se> wrote:
That really depends on the context.

In your example you're doing nothing else then throwing exceptions in a console
application and, as you yourself state, only at one level deep.
Although I also give the figures for throwing an exception 20 stack
frames - my laptop throws 42 of those per millisecond. I can't see how
using ASP.NET would make any difference.
Using a different scenario,

Create an ASP.NET application and let it throw a couple of exceptions around
the call stack. Put a thousand or so worth of user load on the app with ACT
and measure throughput. Then get rid of the exception and do another measure.
You will see a significant increase in the throughput for the application
with less exceptions.
Do you have any statistics and code handy? I would be interested to see
that increase and investigate it. You see, to have an exception or two
making a significant difference means that there has to be a
significant CPU load on the web server to start with. If most of the
time spent on the request is actually waiting for the database, then
changing the time taken by a fortieth of a millisecond is unlikely to
make much odds. It might happen in an app which doesn't actually have
any work to do - but I doubt that there are many apps of that nature
which actually get enough hits for exceptions to make a difference. For
an exception which takes 1/42 milliseconds to throw to make a 5%
difference, the whole request has to take less than half a millisecond
to execute - 2000 requests per second, or 7 million per hour. And
that's only if *every* request throws a 20-stackframe-deep exception,
in which case something is very clearly wrong. If only one in ten hits
throw the exception, the for those hits to make a 5% difference to
overall performance (assuming a CPU bottleneck) then the average time
taken by a request would have to be even smaller.
Regardless of the performance issue, there's a semantic and architectural
issue to consider as well.


Do you mind if we just address the performance issue for the moment?
I'd like to come back to the semantics later, but I suspect if we mix
up the two we'll get in a muddle. Or I will at least. (It would also
take me longer to write about now, and I want to go to bed very soon.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 22 '06 #7

Only reasonable to show code and stats for a claim like this. I will set
up a scenario I use in my perf/scalability classes in the morning. I too
want to get to bed soon :)

--
Patrik Löwendahl [C# MVP]
http://www.lowendahl.net
http://www.cornerstone.se
Patrik Löwendahl [C# MVP] <pa**************@n0spam.home.se> wrote:
That really depends on the context.

In your example you're doing nothing else then throwing exceptions in
a c

onsole
application and, as you yourself state, only at one level deep.

Although I also give the figures for throwing an exception 20 stack
frames - my laptop throws 42 of those per millisecond. I can't see how
using ASP.NET would make any difference.
Using a different scenario,

Create an ASP.NET application and let it throw a couple of exceptions
aro

und
the call stack. Put a thousand or so worth of user load on the app
with A

CT
and measure throughput. Then get rid of the exception and do another
meas

ure.
You will see a significant increase in the throughput for the
application

with less exceptions.

Do you have any statistics and code handy? I would be interested to
see that increase and investigate it. You see, to have an exception or
two making a significant difference means that there has to be a
significant CPU load on the web server to start with. If most of the
time spent on the request is actually waiting for the database, then
changing the time taken by a fortieth of a millisecond is unlikely to
make much odds. It might happen in an app which doesn't actually have
any work to do - but I doubt that there are many apps of that nature
which actually get enough hits for exceptions to make a difference.
For an exception which takes 1/42 milliseconds to throw to make a 5%
difference, the whole request has to take less than half a millisecond
to execute - 2000 requests per second, or 7 million per hour. And
that's only if *every* request throws a 20-stackframe-deep exception,
in which case something is very clearly wrong. If only one in ten hits
throw the exception, the for those hits to make a 5% difference to
overall performance (assuming a CPU bottleneck) then the average time
taken by a request would have to be even smaller.
Regardless of the performance issue, there's a semantic and
architectural

issue to consider as well.

Do you mind if we just address the performance issue for the moment?
I'd like to come back to the semantics later, but I suspect if we mix
up the two we'll get in a muddle. Or I will at least. (It would also
take me longer to write about now, and I want to go to bed very soon.)

Jan 22 '06 #8
Patrik Löwendahl [C# MVP] <pa**************@n0spam.home.se> wrote:
Only reasonable to show code and stats for a claim like this. I will set
up a scenario I use in my perf/scalability classes in the morning. I too
want to get to bed soon :)


Great, thanks. I'll look forward to trying to reproduce your results
and tweak them etc :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 22 '06 #9
I do not believe that exceptions should be used for flow control. Exceptions
should be used for errors. I think it is more appropriate to say that
Exceptions should be used for unexpected errors.

For example, if a user supplies a login/password to login into a database,
and that fails, is that reason enough for an exception? In an interactive
situation I would not consider this appropriate for an exception. In a batch
situation, where the login/password has been "preset", I would probably
consider this an exception.

If you are lamenting the need to add if tests to your code to test for
return values, consider the alternative of adding heaps of nested try-catch
blocks to your code. In terms of readability, I will take the return values
any day over a bunch of try/catch blocks.

"stax" <_r************************@yahoo.de> wrote in message
news:dq**********@online.de...
Hi,

Assuming having a method that calls another method which also calls other
methods and so on having a long winded tree of methods. What do I do in
case it turns out everything has to be aborted? The only reasonable way I
see here is to use a exception but everybody is telling exceptions should
not be used for control flow. I just can't think of another reasonable way
to deal with this.

Are there any good books that teach how to do great architecture?

thanks in advance
Frank

Jan 23 '06 #10
> What do I
do in case it turns out everything has to be aborted?


what do you mean with 'everything has to be aborted'? can you give some
more information on the reason why en how you want to abort those methods?
Jan 23 '06 #11
Patrik Löwendahl [C# MVP] <pa**************@n0spam.home.se> wrote:
Only reasonable to show code and stats for a claim like this. I will set
up a scenario I use in my perf/scalability classes in the morning. I too
want to get to bed soon :)


Any progress on this? I'm intrigued to see what your results are like.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 26 '06 #12

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Andrzej | last post: by
14 posts views Thread by John Spiegel | last post: by
reply views Thread by Radu | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.