|
-
December 14th, 2009, 12:51 PM
#1
[RESOLVED] Transactional programming - how do you solve it? (no DB here)
This time I'd like to ask you how do you solve such a problem that there are few steps that have to be performed in a method but it's like a transaction, this means if one step fails the function returns false.
I know three ways how to do it. With the last one I just came up today and currenty it's my favourite. Here they are:
1:
Code:
bool DoSomething()
{
bool success = false;
try
{
if(DoSomethingElse1() == false)
throw new Exception("Some description");
// ... more code here
if(DoSomethingElse2() == false)
throw new Exception("Something else2 went wrong.");
success = true;
}
catch(Exception ex)
{
// ...
}
finally
{
// ... some clean up etc.
}
return success;
}
Try/catch is a very clear way to do it, but the performance drops when the function gets called many times and it often fails.
2:
Code:
bool DoSomething()
{
if(DoSomethingElse1() == false)
{
// .. do some clean up here etc.
return false;
}
// ... more code here
if(DoSomethingElse2() == false)
{
// .. do some more clean up
return false;
}
return true;
}
this one I think is quite fast but I have to clean up on each fail so it is lots of redundant code.
3:
Code:
bool DoSomething()
{
bool success = false;
do
{
if(DoSomethingElse1() == false)
break;
// ... more code here
if(DoSomethingElse2() == false)
break;
success = true;
}
while(false);
// ... some clean up etc.
return success;
}
so, this is my latest invention ;]
what do you think about all of them? have you other ways to do this kind of transaction in your code?
win7 x86, VS 2008 & 2010, C++/CLI, C#, .NET 3.5 & 4.0, VB.NET, VBA... WPF is comming
remeber to give feedback  you think my response deserves recognition? perhaps you may want to click the Rate this post link/button and add to my reputation
private lessons are not an option so please don't ask for help in private, I won't replay
if you use Opera and you'd like to have the tab-button functionality for the texteditor take a look at my Opera Tab-UserScirpt; and if you know how to stop firefox from jumping to the next control when you hit tab let me know
-
December 14th, 2009, 04:01 PM
#2
Re: Transactional programming - how do you solve it? (no DB here)
Readability is more important than what you're trying to achieve here. The best possible .Net solution (in my opinion) is to use Exceptions.
1) It's known by everyone
2) It's easy to read
3) It's specific (you can specify exactly what went wrong using derived types of System.Exception)
4) It's serializable
It's just the norm. If I opened up some code and saw a bunch of early returns/breaks in a method, I'd most likely refactor it to use Exceptions instead... Go for readability and simplicity and you'll thank yourself later (as will people reading your code).
-
December 15th, 2009, 03:52 AM
#3
Re: Transactional programming - how do you solve it? (no DB here)
I don't like none of your options. I would sugesto something like
Code:
bool DoSomething()
{
try
{
if(DoSomethingElse1() == false) return false;
// ... more code here
if(DoSomethingElse2() == false) return false;
return true;
}
catch(Exception ex)
{
return false; // it is question if catch the exception end return false, or let it raise up the stack; maybe some expected exceptions shoudl be catched, while the remaining no
}
finally
{
// ... some clean up etc.
}
}
In your 1. you gain nothing using exceptions this way, because you don't benefit from any extra piece of information if you throw it and immediately cacht it.
Your 2. lacks the exception handling. If you don't need it, you can go this way.
Your 3. is overcomplicated, you don't need the do-while loop, just return would do the same job.
- Make it run.
- Make it right.
- Make it fast.
Don't hesitate to rate my post. 
-
December 15th, 2009, 04:03 AM
#4
Re: Transactional programming - how do you solve it? (no DB here)
the point is that i cannot return anywhere. i often have to do a lot of cleanup and returning at the point where something went wrong makes the cleanup overcomplicated because i have to repeat the same code each time before i return false.
will the finally block be called if i retun in the try or catch part? besides, try/catch is extreamly slow in some cases and i cannot afford to use it every time.
win7 x86, VS 2008 & 2010, C++/CLI, C#, .NET 3.5 & 4.0, VB.NET, VBA... WPF is comming
remeber to give feedback  you think my response deserves recognition? perhaps you may want to click the Rate this post link/button and add to my reputation
private lessons are not an option so please don't ask for help in private, I won't replay
if you use Opera and you'd like to have the tab-button functionality for the texteditor take a look at my Opera Tab-UserScirpt; and if you know how to stop firefox from jumping to the next control when you hit tab let me know
-
December 15th, 2009, 11:58 AM
#5
Re: Transactional programming - how do you solve it? (no DB here)
1) try/catch is not extremely slow. It's a correct and proper solution.
2) Yes, finally will be hit no matter what
-
December 15th, 2009, 01:52 PM
#6
Re: Transactional programming - how do you solve it? (no DB here)
 Originally Posted by mariocatch
1) try/catch is not extremely slow. It's a correct and proper solution.
i think you believe it's not slow, but you've never tested it or read about it, then see for your self. there is 500miliseconds difference for only 100 tests, if this is not extremly slow...
Code:
private static void TestTransactions()
{
int length = 100;
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
for (int i1 = 0; i1 < length; ++i1)
{
TransactionMethodWithTryCatch(i1);
}
sw.Stop();
Console.WriteLine("try/catch:" + sw.ElapsedMilliseconds); // about 500 miliseconds
sw.Reset();
sw.Start();
for (int i1 = 0; i1 < length; i1++)
{
TransactionMethodWithDoLoop(i1);
}
sw.Stop();
Console.WriteLine("do/while:" + sw.ElapsedMilliseconds); // 0
}
private static bool TransactionMethodWithTryCatch(int num)
{
bool success = false;
try
{
if (true)
throw new Exception("Transaction failed.");
success = true;
}
catch (Exception ex)
{
}
return success;
}
private static bool TransactionMethodWithDoLoop(int num)
{
bool success = false;
do
{
if (true)
break;
success = true;
} while (false);
return success;
}
Last edited by memeloo; December 15th, 2009 at 01:57 PM.
win7 x86, VS 2008 & 2010, C++/CLI, C#, .NET 3.5 & 4.0, VB.NET, VBA... WPF is comming
remeber to give feedback  you think my response deserves recognition? perhaps you may want to click the Rate this post link/button and add to my reputation
private lessons are not an option so please don't ask for help in private, I won't replay
if you use Opera and you'd like to have the tab-button functionality for the texteditor take a look at my Opera Tab-UserScirpt; and if you know how to stop firefox from jumping to the next control when you hit tab let me know
-
December 15th, 2009, 02:09 PM
#7
Re: Transactional programming - how do you solve it? (no DB here)
I use .Net to develop easy, usable, readable, re-usable, and reliable tools. Sacrificing a little speed for a more easily readable, usable solution that any developer doesn't have to strain their eyes over, is worth 500 milliseconds of execution speed IMO.
There's more people in this world than the developer of the program. Might I suggest you read up on .Net Framework Guidelines/Idioms to see where my point of view is coming from, and how it's more important than half a second to me.
-
December 15th, 2009, 02:21 PM
#8
Re: Transactional programming - how do you solve it? (no DB here)
i quite agree with you and i follow this principle most of the time, but there are situations where speed is very important in areas where something has to run smoothly in real time, like a CAD application so i'm trying to keep the code still readable but mutch faster and i think the do/while solution is one of the best... until someone else shows me another clean and good looking way to abbort some operation. thats why i opened this topic.
win7 x86, VS 2008 & 2010, C++/CLI, C#, .NET 3.5 & 4.0, VB.NET, VBA... WPF is comming
remeber to give feedback  you think my response deserves recognition? perhaps you may want to click the Rate this post link/button and add to my reputation
private lessons are not an option so please don't ask for help in private, I won't replay
if you use Opera and you'd like to have the tab-button functionality for the texteditor take a look at my Opera Tab-UserScirpt; and if you know how to stop firefox from jumping to the next control when you hit tab let me know
-
December 16th, 2009, 05:49 AM
#9
Re: Transactional programming - how do you solve it? (no DB here)
C# is not real-time platform (and Windows is not real-time operating system). If the speed is a must, you should consider using C++ instead C#.
- Make it run.
- Make it right.
- Make it fast.
Don't hesitate to rate my post. 
-
December 16th, 2009, 06:05 AM
#10
Re: Transactional programming - how do you solve it? (no DB here)
ok, maybe your're right (i'm too lazy to check it now) but it has to run smoothly. and why should i use c++, xna is after all c# too.
i think further discussion is pointless because most of you are just too conservative. you've learnt the try/catch technique and any other idea is unacceptable even if it's hundered times faster.
edit: oops, it seems that this time i have been to conservative and didn't want to see the new way (to me) of using try/catch. sorry :]
Last edited by memeloo; December 16th, 2009 at 06:58 AM.
win7 x86, VS 2008 & 2010, C++/CLI, C#, .NET 3.5 & 4.0, VB.NET, VBA... WPF is comming
remeber to give feedback  you think my response deserves recognition? perhaps you may want to click the Rate this post link/button and add to my reputation
private lessons are not an option so please don't ask for help in private, I won't replay
if you use Opera and you'd like to have the tab-button functionality for the texteditor take a look at my Opera Tab-UserScirpt; and if you know how to stop firefox from jumping to the next control when you hit tab let me know
-
December 16th, 2009, 06:14 AM
#11
Re: Transactional programming - how do you solve it? (no DB here)
 Originally Posted by memeloo
ok, maybe your're right (i'm too lazy to check it now) but it has to run smoothly. and why should i use c++, xna is after all c# too.
i think further discussion is pointless because most of you are just too conservative. you've learnt the try/catch technique and any other idea is unacceptable even if it's hundered times faster.
XNA isn't that fast.. Its only used for smaller games for a reason..
Not using try catches is just a huge fail in my eyes it has nothing to do with being conservative.. it's just good coding!
Last edited by kristof1104; December 16th, 2009 at 06:25 AM.
-
December 16th, 2009, 06:38 AM
#12
Re: Transactional programming - how do you solve it? (no DB here)
i think you believe it's not slow, but you've never tested it or read about it, then see for your self. there is 500miliseconds difference for only 100 tests, if this is not extremly slow...
Nope, you've got your numbers wrong somewhere. I ran it locally and with 1,000,000 iterations the difference was 2seconds versus 2ms. However, this is still a bad test as you shouldn't be throwing those exceptions anyway because you could just return false (see below). Throwing exceptions is slow as you have to generate a stacktrace every time an exception is thrown and this is slow. The overhead of try/catch or try/finally is negligible.
The best solution is as already mentioned:
Code:
bool DoSomething()
{
ResourceNeedingCleanup c = new ResourceNeedingCleanup ();
try
{
if(!DoSomethingElse1())
return false;
// ... more code here
if(!DoSomethingElse2())
return false;
}
finally {
c.Cleanup ();
// ... some clean up etc. - Will always be executed. Always.
}
return true;
}
Note that there's no 'catch' here because if an exception does occur this function doesn't know how to handle it. If you can actually handle the exception properly, then add a 'catch' here with your error handling.
i think further discussion is pointless because most of you are just too conservative. you've learnt the try/catch technique and any other idea is unacceptable even if it's hundered times faster.
No, we're not conservative. We just have a lot of experience and know what works and what doesn't. Throwing exceptions to control the flow of a function is bad and not using try/finally to clean up resources which *must* be cleaned up is also bad.
Last edited by Mutant_Fruit; December 16th, 2009 at 06:41 AM.
www.monotorrent.com For all your .NET bittorrent needs
NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.
-
December 16th, 2009, 06:54 AM
#13
Re: Transactional programming - how do you solve it? (no DB here)
thx @Mutant_Fruit for the re-explanation and thx @boudino for the suggestion ... i like it. and sorry that i've jumped to conlusions without testing it :] oh, and of course thx for your patience i would say this is the ultimate solution.
win7 x86, VS 2008 & 2010, C++/CLI, C#, .NET 3.5 & 4.0, VB.NET, VBA... WPF is comming
remeber to give feedback  you think my response deserves recognition? perhaps you may want to click the Rate this post link/button and add to my reputation
private lessons are not an option so please don't ask for help in private, I won't replay
if you use Opera and you'd like to have the tab-button functionality for the texteditor take a look at my Opera Tab-UserScirpt; and if you know how to stop firefox from jumping to the next control when you hit tab let me know
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|