Is this a dangerous locking pattern? - c#

I have an enumerator written in C#, which looks something like this:
try
{
ReadWriteLock.EnterReadLock();
yield return foo;
yield return bar;
yield return bash;
}
finally
{
if (ReadWriteLock.IsReadLockHeld)
ReadWriteLock.ExitReadLock();
}
I believe this may be a dangerous locking pattern, as the ReadWriteLock will only be released if the enumeration is complete, otherwise the lock is left hanging and is never released, am I correct? If so, what's the best way to combat this?

No, the finally block will always be executed, pretty much unless somebody pulls the plug from the computer (well and a few other exceptions).
public static IEnumerable<int> GetNumbers() {
try
{
Console.WriteLine("Start");
yield return 1;
yield return 2;
yield return 3;
}
finally
{
Console.WriteLine("Finish");
}
}
...
foreach(int i in GetNumbers()) {
Console.WriteLine(i);
if(i == 2) break;
}
The output of the above will be
Start12Finish
Note that in C# you write yield return, not just yield. But I guess that was just a typo.

I think David's answered the question you intended to ask (about the enumeration aspect), but two additional points to consider:
What would happen if ReadWriteLock.EnterReadLock threw an exception?
What would happen if ReadWriteLock.ExitReadLock threw an exception?
In #1, you'll call ReadWriteLock.ExitReadLock inappropriately. In #2, you may hide an existing exception that's been thrown (since finally clauses happen either because the mainline processing reached the end of the try block or because an exception was thrown; in the latter case, you probably don't want to obscure the exception). Perhaps both of those things are unlikely in this specific case, but you asked about the pattern, and as a pattern it has those issues.

Finally will be executed in any way, but for locking in may not be safe. Compare following methods:
class Program
{
static IEnumerable<int> meth1()
{
try
{
Console.WriteLine("Enter");
yield return 1;
yield return 2;
yield return 3;
}
finally
{
Console.WriteLine("Exit");
}
}
static IEnumerable<int> meth2()
{
try
{
Console.WriteLine("Enter");
return new int[] { 1, 2, 3 };
}
finally
{
Console.WriteLine("Exit");
}
}
static public void Main()
{
foreach (int i in meth1())
{
Console.WriteLine("In");
}
Console.WriteLine();
foreach (int i in meth2())
{
Console.WriteLine("In");
}
}
}
Output is:
Enter
In
In
In
Exit
Enter
Exit
In
In
In
If your processing takes much time (per iteration) it is more reasonable to fill collection first, then process, but not yield.

Related

What is and is not recursion?

I'm trying to understand what exactly is recursion and have not been able to find an answer to the following.
My current understanding of recursion is that it is anytime a method calls itself.
I.E
Menu()
{
if(i<2)
{Console.WriteLine();}
else
{Menu();}
}
The above is an example of recursion a method calling itself.
What I'm not sure about is a scenario like:
Menu()
{
if(i<2)
{Console.WriteLine();}
else
{Console.WriteLine("Something Went Wrong!"); MenuError();}
}
MenuError()
{
Console.WriteLine("Something went wrong!");
Menu();
}
If the method calls a method which then calls it is this still recursion ?
My current understanding of recursion is that it is anytime a method
calls itself.
That is correct. Recursive definitions are self-referencing definitions.
Two interesting properties of recursive definitions are productivity and termination. A program is productive if it continues to yields output, though the full output may never come (hence it may not terminate). A program terminates if it yields its full output in finite time.
For example, this is a productive, non-terminating program:
Naturals(int i) {
Console.WriteLine(i);
Naturals(i + 1);
}
This is a terminating program:
UpToTen(int i) {
Console.WriteLine(i);
if (i < 10) UpToTen(i + 1);
}
This is a non-productive program:
DoNothing() {
DoNothing();
}
If Menu calls MenuError, and MenuError calls Menu, this is sometimes called mutual recursion. The only difference is our organisation; we can rewrite the code to just have one method by inlining MenuError.
Menu() {
if (i < 2) {
Console.WriteLine();
}
else {
Console.WriteLine("Something Went Wrong!");
Console.WriteLine("Something went wrong!");
Menu();
}
}
You can in fact abstract recursion itself:
// General definition
A Fix<A>(Func<Func<A>,A> f) {
return f(() => Fix(f));
}
// Special definition for void functions
void Fix(Action<Action> f) {
f(() => Fix(f));
}
void Menu(Action menu) {
if (i < 2) {
Console.WriteLine();
}
else {
Console.WriteLine("Something Went Wrong!");
Console.WriteLine("Something went wrong!");
menu();
}
}
Fix(Menu);
Here is another example using Fix to define the factorial function.
Func<int, int> Fac(Func<Func<int, int>> fac) {
return i => i == 0 ? 1 : i * fac()(i - 1);
}
// Fix<Func<int, int>>(Fac) is the factorial function
You may wonder why Fix does not have the signature A Fix<A>(Func<A,A> f) instead. This is because C# is a strict language, meaning it evaluates arguments before it evaluates function application. With the simpler signature the C# program would end up in infinite recursion.
Yes it is still recursion. There are different types of recursion like Tail recursion, Tree Recursion etc. You can check out google for rest.
By the way, in the second case, if value of i is greater than or equal to 2, you will get stack overflow error as each one will call another one.

Infinite state machine with an IDisposable

Lets say I have an infinite state machine to generate random md5 hashes:
public static IEnumerable<string> GetHashes()
{
using (var hash = System.Security.Cryptography.MD5.Create())
{
while (true)
yield return hash.ComputeHash(Guid.NewGuid().ToByteArray());
}
}
In the above example I use an using statement. Will the .Dispose() method ever be called? CQ, will the unmanaged resources ever be freed?
For example, if I use the machine as follows:
public static void Test()
{
int counter = 0;
var hashes = GetHashes();
foreach(var md5 in hashes)
{
Console.WriteLine(md5);
counter++;
if (counter > 10)
break;
}
}
Since the hashes variable will go out of scope (and I presume garbage collected) will the dispose method be called to free the resources used by System.Security.Cryptography.MD5 or is this a memory leak?
Let's change your original code blocks a bit to boil it down to the essentials, while still keeping it interesting enough to analyze. This is not exactly equivalent to what you posted, but we're still using the value of the iterator.
class Disposable : IDisposable {
public void Dispose() {
Console.WriteLine("Disposed!");
}
}
IEnumerable<int> CreateEnumerable() {
int i = 0;
using (var d = new Disposable()) {
while (true) yield return ++i;
}
}
void UseEnumerable() {
foreach (int i in CreateEnumerable()) {
Console.WriteLine(i);
if (i == 10) break;
}
}
This will print the numbers from 1 to 10 before printing Disposed!
What actually happens under the covers? A whole lot more. Let's tackle the outer layer first, UseEnumerable. The foreach is syntactic sugar for the following:
var e = CreateEnumerable().GetEnumerator();
try {
while (e.MoveNext()) {
int i = e.Current;
Console.WriteLine(i);
if (i == 10) break;
}
} finally {
e.Dispose();
}
For the exact details (because even this is simplified, a little) I refer you to the C# language specification, section 8.8.4. The important bit here is that a foreach entails an implicit call to the Dispose of the enumerator.
Next, the using statement in CreateEnumerable is syntactic sugar as well. In fact, let's write out the whole thing in primitive statements so we can make more sense of the translation later:
IEnumerable<int> CreateEnumerable() {
int i = 0;
Disposable d = new Disposable();
try {
repeat:
i = i + 1;
yield return i;
goto repeat;
} finally {
d.Dispose();
}
}
The exact rules for implementation of iterator blocks are detailed in section 10.14 of the language specification. They're given in terms of abstract operations, not code. A good discussion on what kind of code is generated by the C# compiler and what each part does is given in C# in Depth, but I'm going to give a simple translation instead that still complies with the specification. To reiterate, this is not what the compiler will actually produce, but it's a good enough approximation to illustrate what's happening and leaves out the more hairy bits that deal with threading and optimization.
class CreateEnumerable_Enumerator : IEnumerator<int> {
// local variables are promoted to instance fields
private int i;
private Disposable d;
// implementation of Current
private int current;
public int Current => current;
object IEnumerator.Current => current;
// State machine
enum State { Before, Running, Suspended, After };
private State state = State.Before;
// Section 10.14.4.1
public bool MoveNext() {
switch (state) {
case State.Before: {
state = State.Running;
// begin iterator block
i = 0;
d = new Disposable();
i = i + 1;
// yield return occurs here
current = i;
state = State.Suspended;
return true;
}
case State.Running: return false; // can't happen
case State.Suspended: {
state = State.Running;
// goto repeat
i = i + 1;
// yield return occurs here
current = i;
state = State.Suspended;
return true;
}
case State.After: return false;
default: return false; // can't happen
}
}
// Section 10.14.4.3
public void Dispose() {
switch (state) {
case State.Before: state = State.After; break;
case State.Running: break; // unspecified
case State.Suspended: {
state = State.Running;
// finally occurs here
d.Dispose();
state = State.After;
}
break;
case State.After: return;
default: return; // can't happen
}
}
public void Reset() { throw new NotImplementedException(); }
}
class CreateEnumerable_Enumerable : IEnumerable<int> {
public IEnumerator<int> GetEnumerator() {
return new CreateEnumerable_Enumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
}
IEnumerable<int> CreateEnumerable() {
return new CreateEnumerable_Enumerable();
}
The essential bit here is that the code block is split up at the occurrences of a yield return or yield break statement, with the iterator responsible for remembering "where we were" at the time of the interruption. Any finally blocks in the body are deferred until the Dispose. The infinite loop in your code is really not an infinite loop anymore, because it's interrupted by periodic yield return statements. Note that, because the finally block isn't actually a finally block anymore, it getting executed is a little less certain when you're dealing with iterators. This is why using foreach (or any other way that ensures the Dispose method of the iterator is called in a finally block) is essential.
This is a simplified example; things get much more interesting when you make the loop more complex, introduce exceptions, etcetera. The burden of "just making this work" is on the compiler.
Largely, it depends on how you code it. But in your example, Dispose will be called.
Here's an explanation on how iterators get compiled.
And specifically, talking about finally:
Iterators pose an awkward problem. Instead of the whole method executing before the stack frame is popped, execution effectively pauses each time a value is yielded. There's no way of guaranteeing that the caller will ever use the iterator again, in any way, shape or form. If you require some more code to be executed at some point after the value is yielded, you're in trouble: you can't guarantee it will happen. To cut to the chase, code in a finally block which would normally be executed in almost all circumstances before leaving the method can't be relied on quite as much.
...
The state machine is built so that finally blocks are executed when an iterator is used properly, however. That's because IEnumerator implements IDisposable, and the C# foreach loop calls Dispose on iterators (even the nongeneric IEnumerator ones, if they implement IDisposable). The IDisposable implementation in the generated iterator works out which finally blocks are relevant to the current position (based on the state, as always) and execute the appropriate code.

Does Recursive call works as goto?

I have a method that i have to call it from itself for multiple times in order to get a result and i want to know is Recursive call work as goto in this situation ?
Dummy Code:
public int DummyMethod()
{
string token;
int result = -1;
token = GetNewToken();
Stopwatch stopwatch = Stopwatch.StartNew();
while (result == -1)
{
if (stopwatch.Elapsed >= TimeSpan.FromSeconds(350)) {
//This is related to some logic as the token for the website
//expires after 350 seconds.
result = DummyMethod();
continue; //DO I NEED TO USE contunue ? or the recursive
//call broke the method (as if i used goto)
}
result = GetResultFromWebSite(token);
}
return result;
}
I think you have this all wrong and you definitely shouldn't be trying to figure out if your token has expired. This should be something the server tells you. If it comes via an exception you could do something like this:
public int DummyMethod(int retries = 0)
{
string token;
try
{
token = GetNewToken();
return GetResultFromWebSite(token);
}
catch (Exception e)
{
if (retries < 4) // or whatever max you want - you probably shouldn't hardcode it
{
return DummyMethod(++retries);
}
throw new Exception("Server ain't responding");
}
}
In a situation like this, it's often a good idea to have a maximum number of retries after which you will give up and show an error message.
You should instead use
return DummyMethod();
which is a tail call (the compiler can turn it into a goto).
This is a good illustration of one way the "single entry/single return" mantra fails.
However, I'm pretty sure you could just build this into the loop and avoid recursion:
public int DummyMethod()
{
Stopwatch stopwatch = Stopwatch.StartNew();
string token = GetNewToken();
int result;
do
{
if (stopwatch.Elapsed.TotalSeconds >= 350) {
token = GetNewToken();
stopwatch.Restart();
}
result = GetResultFromWebSite(token);
} while (result == -1);
return result;
}
It seems to me that you want to know how to stop the recursion. This is normally done with a condition where the result is clear and returned without calling the recursive function again. This way the endless calling of the recursive method is stopped and the recursion will come to an end. You dont use a goto for that like you simply never should use goto ;)
No, recursive calls are not equivalent to goto statements.
You don't even need to use recursion to solve your problem. If you place your call to GetNewToken in the loop, you can check the result and use continue to perform another iteration if you don't get the desired results. If you do get the desired result, you can call GetResultFromWebSite and return its result immediately.

try finally mystery

Consider,
static void Main(string[] args)
{
Console.WriteLine(fun());
}
static int fun()
{
int i = 0;
try
{
i = 1;
return i;
}
catch (Exception ex)
{
i = 2;
return i;
}
finally
{
i = 3;
}
}
The sample code outputs "1". but the value of i is changed to 3 in finally block. Why wasn't the value of 'i' changed to 3?
Thank you,
Consider this code- I think the code explains what you are thinking, and how you can make what you think should happen actually happen:
static void Main(string[] args)
{
int counter = 0;
Console.WriteLine(fun(ref counter)); // Prints 1
Console.WriteLine(counter); // Prints 3
}
static int fun(ref int counter)
{
try
{
counter = 1;
return counter;
}
finally
{
counter = 3;
}
}
With this code you return 1 from the method, but you also set the counter variable to 3, which you can access from outside the method.
You have to remember that finally executes after everything else in the try and catch. Place the return statement after the try/catch/finally statement to have it return 3.
I imagine if you use a reference type instead of a value type you'd get different behavior.
When you said "return i"... C# puts that return value in a temporary holding area (memory) and then runs your 'finally' code... if the finally block was able to modify that value, it would defeat the safety/finalism of the finally block.
It's like a using statement with a return inside... the "Dispose" is still going to happen, AFTER the return (so to speak).
Finally is always executed
Your code always executes finally no matter if an exception was thrown or not. So your code should actually be:
try
{
i = 1;
}
catch
{
i = 2;
}
finally
{
i = 3;
}
return i;
But in this trivial case finally block won't make much sense. Because we will always return 3 no matter what happened before that.
Finally is used to release resources
finally block should normally be used when you have to release some system resources allocated within try block (ie. openning a DB connection an reading data in try block and closing it in finally). So they will always get released no matter if there was an exception or not. In this case it doesn't make much sense to use finally block.

How to explicitly pass a program flow into the finally block in C#?

In Delphi I could do something like this:
try
if not DoSomething then
Exit;
if not DoSomething2 then
Exit;
if not DoSomething3 then
Exit;
finally
DoSomethingElse;
end;
In other means if method DoSomething results false then the program flow is transffered to the finally block and DoSomething2 and DoSomething3 are not executed.
How to achieve such behaviour in C#?
Thanks in advance.
Edit1:
The below example doesn't compile in VS 2008
Edit2: I am sorry I was to fast and forget the return statement;
XElement OrderStatus(q_order_status Request)
{
XElement Response;
try
{
if (DoSomething() != 0 )
{
return;
}
}
catch(Exception e)
{
// catch some errors and eventually pass the e.Message to the Response
}
finally
{
Response = new XElement("SomeTag", "SomeResponse");
}
return Response;
}
Edit3:
After testing it seems that the easiest way to achieve this is to throw an exception if the result of DoSomething1 is false. I can throw my own execption, write a specific message and pass it to the finally clause.
You really shouldn't be using exception handling constructs for flow control. That said, Exit is comparable to return in C#. As the MSDN Documentation about the [return keyword][1] says:
If the return statement is inside a try block, the finally block, if one exists, will be executed before control returns to the calling method.
In general a finally-block will almost always execute if the corresponding try-block has been reached. There are a few rare situations where it is impossible to guarantee that the finally-block executes, but they are all fatal errors, upon which programs should likely immediately crash.
How your code would look in C#:
try
{
if (!DoSomething())
return;
if (!DoSomething2())
return;
if (!DoSomething3())
return;
}
finally
{
DoSomethingElse();
}
But again, don't do this. try and finally are intended for handling exceptions, not for normal flow control.
Reply to your edit:
In your code return doesn't compile because the return type of the method is XElement and return by itself can only be used when the return type is void. You could use return new XElement("SomeTag", "SomeResponse");, as that is what the finally would be doing anyway, or you could assign Response earlier and do return Response;.
Note though that while the finally always executes, the return Response; that comes after it doesn't execute if the reason went into the finally-block is because you did a return inside the try-block.
Answer to updated question:
The reason you're having trouble doing this in an elegant way, is because you seem to be using a combination of return values and exceptions. You should consider manually raising an exception instead of using return values if the sitation is, well, exceptional.
Assuming there is a good reason for the return values however, I'm thinking it might be clearer to go without a finally block altogether, and to include a return at the end of the try block and also in your catch block. That would save you from passing the exception message in a messy way.
I can't really say what the best solution would be, since your code snippet does not show what Response would be if DoSomething() returns a non-zero value.
Original answer:
It depends a little on what you're trying to accomplish. Are exceptions actually being thrown in any of the methods? Otherwise there is no good reason to use a try-finally pattern. This would be equivalent (though maybe not advisable for readability):
bool doneEverything = DoSomething() && DoSomething2() && DoSomething3();
DoSomethingElse();
If there are exceptions being thrown, and handled at a higher level, I'd recommend isolating this code in a separate method, so you can use a return statement*.
void DoStuff()
{
try
{
if (!DoSomething())
return;
if (!DoSomething2())
return;
if (!DoSomething3())
return;
}
finally
{
DoSomethingElse();
}
}
To answer your question about when the finally code block is executed: it is always executed, unless the executing thread terminates prematurely.
*: Some restructuring is recommended, because there is no equivalent of the Delphi Exit. The break statement comes closest, but it can only be used in loop constructs or switch blocks. To mimic Exit behavior, you would need goto and a label. We wouldn't want that, now would we? :)
Why not make the three try-lines a common if/else block? Instead of exit, call the DoSomethingElse. Like so:
if (DoSomething() == false)
{
DoSomethingElse();
}
else if (DoSomething2() == false)
{
DoSomethingElse();
}
else if (DoSomething3() == false)
{
DoSomethingElse();
}
I would like to say that "C# is not Delphi", but that would be a bit arrogant.
In C#, finally is executed as well when return is called inside the try statement.
bool doSomething = false;
bool doSomething2 = true;
try
{
if( !doSomething )
{
Console.WriteLine ("not dosomething");
return;
}
if( !doSomething2 )
{
Console.WriteLine ("not dosomething 2");
return;
}
}
finally
{
Console.WriteLine ("In finally");
}
What about switch case of course If you don't mean the finally in c# by saying finally block. default case is the finally block then and you can also find flow control example and here at msdn : Flow Control (C# vs. Java)
static void Main(string[] args)
{
switch (args[0])
{
case "copy":
//...
break;
case "move":
//...
goto case "delete";
case "del":
case "remove":
case "delete":
//...
break;
default:
//...
break;
}
}
In this sort of situation, understanding the question as dealing exclusively with the non-exception handling case, I would refactor the contents of the try into a private helper method, like this
void BranchOnContext()
{
if (!DoSomething())
return;
if (!DoSomething2())
return;
// last one will drop out and return anyway
DoSomething3();
}
void DoStuff()
{
BranchOnContext(); // Assumed not to throw
DoSomethingElse(); // Always the next thing to be executed
}
EDIT -- tracking the changed requirement
void DoStuff()
{
string message = string.Empty;
try {
BranchOnContext();
} catch (MyExpectedException me) { // only catch exceptions I'm prepared to handle
message = me.Message;
}
DoSomethingElse(message); // Always the next thing to be executed
}
Taking another crack at this with the updated info:
I want DoSomethingElse to be executed
always and I want it to include
message from possible exception
If any of the DoSomething's return 0, null is returned. If not, the generic message is created. If there was an exception, it is caught and a message with its info is returned. How about this?
XElement OrderStatus(q_order_status Request)
{
try
{
if (DoSomething() != 0 )
{
return null;
}
else
{
return new XElement("SomeTag", "SomeResponse");
}
}
catch(Exception e)
{
// catch some errors and eventually pass the e.Message to the Response
return new XElement(e.tag, e.response);
}
}
Im still struggling with how to, in a good way, put finally into this.
I find it quite similar in behavior to the Delphi's one which I have shown on the beginning. I am interested in your comments. Response is dependent on the DoSomethings result.
XElement OrderStatus(q_order_status Request)
{
XElement Response;
int result = 0;
string Message = "";
try
{
result = DoSomething1();
if (result != 0)
{
throw new DoSomethingException("DoSomething1 has failed!");
}
result = DoSomething2();
if (result != 0)
{
throw new DoSomethingException("DoSomething2 has failed!");
}
result = DoSomething3();
if (result != 0)
{
throw new DoSomethingException("DoSomething3 has failed!");
}
Message = "All tests has been passed.";
}
catch(DoSomethingException e)
{
Message = e.Message;
}
catch(Exception e)
{
Message = e.Message;
}
finally
{
Response = new XElement("SomeTag", Message);
}
return Response;
}
What do you think?
void funcA()
{
if (!DoSomething())
return;
if (!DoSomething2())
return;
if (!DoSomething3())
return;
}
void funcB()
{
funcA();
DoSomethingElse;
}
This appears to replicate the delphi:-
try
{
if(DoSomething())
if(DoSomething2())
DoSomething3();
}
finally
{
DoSomethingElse();
}
an alternate style (some people will hate this style, others will love it.):-
try
{
DoSomething() && DoSomething2() && DoSomething3();
}
finally
{
DoSomethingElse();
}
I get the impression you want some other behaviour though?
Goto version?
try
{
if (!DoSomething())
goto Exit;
if (!DoSomething2())
goto Exit;
if (!DoSomething3())
goto Exit;
Exit:;
}
finally
{
DoSomethingElse();
}
Note the irritating ; after the label, it seems a label must precede a statement.
Just had an epiphany:-
Func<bool>[] somethings = new Func<bool>[] {DoSomething, DoSomething2, DoSomething3};
try
{
foreach (Func<bool> something in somethings)
{
if (!something())
break;
}
}
finally
{
DoSomethingElse();
}

Categories

Resources