foreach (var thing in things)
{
tryagain:
string thing.var1 = ThisCanReturnNullSometimes();
if (thing.var1 == null)
{
goto tryagain;
}
}
I know ideally you don't want a method that can "fail" but I'm working with the youtube data API and for some reason some calls just.. don't follow through.
It seems like a short and sweet way to reattempt the iteration, but i've never used a goto before and I've only heard people say don't use it.
Most programs can be expressed without goto. In this particular case, a loop is a far more readable construct, because it says pretty much what you want it to say:
string x;
do {
x=CanReturnNullSometimes();
} while (x==null);
One nice thing about this loop is that the readers always know its post-condition: the only way this loop can terminate is that x becomes non-null. You can also add safety check to ensure that you are not calling the method too many times.
Your goto is safe, but is generally not used. Essentially you have written an implementation of a while loop.
But your code does have an interesting trait, your variable can be scoped and assigned and still be available after the loop... which can be concisely done like :-
tryagain: var s = ThisCanReturnNullSometimes();
if (s == null) goto tryagain;
however, while that is interesting.... I'd stick with a while loop or helper method if you'd like it more concise
Of course, it also has the additional problem of being an infinite loop in the case of null being returned all the time.
You would probably be better off using something like a while loop to monitor the status of your method and keep trying it. You could add a maximum iteration check to make sure it doesn't just loop forever.
string thing.var1 = ThisCanReturnNullSometimes();
int iteration = 0;
while (thing.var1 == null && iteration < 5)
{
Thread.Sleep(5000); // sleep for a bit to give the remove service time to "work"
thing.var1 = ThisCanReturnNullSometimes();
iteration++;
}
This will sleep for 5 seconds then try the method again and repeat up to 5 times before continuing on.
Of course, the best way would be to work out why your method fails, if it's a common problem or something that can be fixed.
Related
As all coders I hate repeated blocks of code, but as a C++ dev I really want the null checks as it has been burnt into me meaning a have a lot of blocks that look like
if(object == null)
{
//For loops
continue;
//To check function inputs/creation
return; //maybe with a value
}
I know I could put a try/catch around everything, but I really don't like that style of coding
Is there a way to replace the null check block with a generic function. Something like
jumpstatement CheckNull<T>(T thingToCheck)
{
if(thingToCheck == null)
{
return continue;
}
return null;
}
Then in the actual code instead of the old repeated blocks I'd have just the function (padded out as requested)
for(int i = 0; i < myCollection.Count; i++){
//Function forces a "continue;" call if null
CheckNull(myCollection[i]);
//Do some stuff with myCollection[i]
}
The closest thing I could see was talking about code snippits or inline functions but I really don't think that's what I want.
I don't think what you want to do here is possible. Basically, you want to be able to call a function which affects control flow in the function calling it (e.g. you want to be able to return from the calling function from your function). This is not possible with a normal function.
This sort of thing is possible in C/C++ using function-like macros, and in several other languages which support "real" macros. Unfortunately, C# does not have macros, so this sort of thing can't be done in the way you want.
C# 8 has a new feature called nullable reference types that's even better. You add a few annotations here and there, and then the compiler can handle a lot of this for you. You get to just write the code you want to write, without worrying a reference might accidentally be null. It takes some getting used to, but it's pretty cool once you've mastered the concept.
Aside from that, you can't return an arbitrary jump or goto... but you can return a delegate. This is similar to C/C++ function pointer. You can theoretically use this to turn this proposed call:
CheckNull(someObject);
into this:
CheckNull(someObject)();
where the return value of CheckNull() is a method you want to call. But more practically, it would probably look more like this:
CheckNull(someObject, o => {
//Do something with someObject here, where you can be **sure** someObject is not null
});
You could even embed a lock into your method to keep things more thread-safe.
public void CheckNull<T>(T target, Action<T> action)
{
if (target is object)
{ //naive implementation -- potential thread race between these two lines
// ... but it does narrow the race to JUST those two lines, regardless of how much work is hidden in the action.
lock(target)
{
action(target);
}
}
}
The other thing you can do is use Where() operation. So if you have an array like this
object[] items = new object[100];
FillArray(items);
You can write code like this loop over only the items that are not null:
foreach(var item in items.Where(i => i is object))
{
//item will not be null, as long as you're in a single thread. Otherwise, lock on something first.
}
We are looking through our code trying to identify high CPU usage, and I am looking at several areas where we use while loops. I would like to take the risk of infinite loops out of the code shown below, but I am not sure what the best solution would be.
IDictionaryEnumerator codeEnumerator = Resources.Error_Codes.ResourceManager.GetResourceSet(CultureInfo.CurrentCulture, true, true).GetEnumerator();
IDictionaryEnumerator messageEnumerator = Resources.Error_Messages.ResourceManager.GetResourceSet(CultureInfo.CurrentCulture, true, true).GetEnumerator();
bool codeDone = false;
bool messageDone = false;
while (codeEnumerator.MoveNext() && !codeDone)
{
string value = codeEnumerator.Value.ToString();
if (value == failedResponse.Code.ToString())
{
key = codeEnumerator.Key.ToString();
codeDone = true;
}
}
while (messageEnumerator.MoveNext() && !messageDone)
{
if (messageEnumerator.Key.ToString() == key)
{
message = messageEnumerator.Value.ToString();
messageDone = true;
}
}
Assuming that the underlying sequence are finite, not infinite, (which you have said is the case) then the loops will not run forever.
Eventually you can be sure that one of the following things will happen:
The if will be true for a given item, thus setting the boolean and breaking out of the loop.
You will advance to the end of the sequence, thus resulting in MoveNext being false.
An exception will be thrown from somewhere, such as from the underlying collection being modified by another thread, by a null value in the sequence, or anything else. As you have no try/catch, this will break you out of the loop.
In particular, since each iteration of the loop must advance the iterator (due to MoveNext) you can be sure that you will eventually end.
Looking at your code and trying to figure out what your dictionaries are actually named, I think you're looking for something like this:
var key = Error_Codes.FirstOrDefault(kvp => kvp.Value.ToString =
failedResponse.Code.ToString()).Select(kvp => kvp.Key);
string message = string.Empty;
if(null != key)
message = Error_Messages[key];
This assumes your dictionaries are Error_Codes and Error_Messages.
As Eric pointed out in the comments, there were issues with the way you were using iterators and dictionaries. This does away with the iterator problems, but this still isn't an ideal way to use dictionaries.
If you have a unique list of error messages and error code keys, then you could have a dictionary that maps the two together. Alternatively, you could combine the dictionaries with a common key set for the dictionary key, and a tuple of error codes and error messages as the dictionary values.
You could start a timer/other thread that sets a second contidion to false if the loop takes more than x time. But i dont think that this is a clean solution either.
You could add a counter that counts down in the while loop. Set the counter real high to a value like 100 or so and When the counter reaches zero, exit the loop. It means that its possible it might terminate before the operation is completely carried out, but it means it will eventually exit.
Let's think of it as a family tree, a father has kids, those kids have kids, those kids have kids, etc...
So I have a recursive function that gets the father uses Recursion to get the children and for now just print them to debug output window...But at some point ( after one hour of letting it run and printing like 26000 rows) it gives me a StackOverFlowException.
So Am really running out of memory? hmmm? then shouldn't I get an "Out of memory exception"? on other posts I found people were saying if the number of recursive calls are too much, you might still get a SOF exception...
Anyway, my first thought was to break the tree into smaller sub-strees..so I know for a fact that my root father always has these five kids, so Instead of Calling my method one time with root passed to it, I said ok call it five times with Kids of root Passes to it.. It helped I think..but still one of them is so big - 26000 rows when it crashes - and still have this issue.
How about Application Domains and Creating new Processes at run time at some certain level of depth? Does that help?
How about creating my own Stack and using that instead of recursive methods? does that help?
here is also a high-level of my code, please take a look, maybe there is actually something silly wrong with this that causes SOF error:
private void MyLoadMethod(string conceptCKI)
{
// make some script calls to DB, so that moTargetConceptList2 will have Concept-Relations for the current node.
// when this is zero, it means its a leaf.
int numberofKids = moTargetConceptList2.ConceptReltns.Count();
if (numberofKids == 0)
return;
for (int i = 1; i <= numberofKids; i++)
{
oUCMRConceptReltn = moTargetConceptList2.ConceptReltns.get_ItemByIndex(i, false);
//Get the concept linked to the relation concept
if (oUCMRConceptReltn.SourceCKI == sConceptCKI)
{
oConcept = moTargetConceptList2.ItemByKeyConceptCKI(oUCMRConceptReltn.TargetCKI, false);
}
else
{
oConcept = moTargetConceptList2.ItemByKeyConceptCKI(oUCMRConceptReltn.SourceCKI, false);
}
//builder.AppendLine("\t" + oConcept.PrimaryCTerm.SourceString);
Debug.WriteLine(oConcept.PrimaryCTerm.SourceString);
MyLoadMethod(oConcept.ConceptCKI);
}
}
How about creating my own Stack and using that instead of recursive methods? does that help?
Yes!
When you instantiate a Stack<T> this will live on the heap and can grow arbitrarily large (until you run out of addressable memory).
If you use recursion you use the call stack. The call stack is much smaller than the heap. The default is 1 MB of call stack space per thread. Note this can be changed, but it's not advisable.
StackOverflowException is quite different to OutOfMemoryException.
OOME means that there is no memory available to the process at all. This could be upon trying to create a new thread with a new stack, or in trying to create a new object on the heap (and a few other cases).
SOE means that the thread's stack - by default 1M, though it can be set differently in thread creation or if the executable has a different default; hence ASP.NET threads have 256k as a default rather than 1M - was exhausted. This could be upon calling a method, or allocating a local.
When you call a function (method or property), the arguments of the call are placed on the stack, the address the function should return to when it returns are put on the stack, then execution jumps to the function called. Then some locals will be placed on the stack. Some more may be placed on it as the function continues to execute. stackalloc will also explicitly use some stack space where otherwise heap allocation would be used.
Then it calls another function, and the same happens again. Then that function returns, and execution jumps back to the stored return address, and the pointer within the stack moves back up (no need to clean up the values placed on the stack, they're just ignored now) and that space is available again.
If you use up that 1M of space, you get a StackOverflowException. Because 1M (or even 256k) is a large amount of memory for these such use (we don't put really large objects in the stack) the three things that are likely to cause an SOE are:
Someone thought it would be a good idea to optimise by using stackalloc when it wasn't, and they used up that 1M fast.
Someone thought it would be a good idea to optimise by creating a thread with a smaller than usual stack when it wasn't, and they use up that tiny stack.
A recursive (whether directly or through several steps) call falls into an infinite loop.
It wasn't quite infinite, but it was large enough.
You've got case 4. 1 and 2 are quite rare (and you need to be quite deliberate to risk them). Case 3 is by far the most common, and indicates a bug in that the recursion shouldn't be infinite, but a mistake means it is.
Ironically, in this case you should be glad you took the recursive approach rather than iterative - the SOE reveals the bug and where it is, while with an iterative approach you'd probably have an infinite loop bringing everything to a halt, and that can be harder to find.
Now for case 4, we've got two options. In the very very rare cases where we've got just slightly too many calls, we can run it on a thread with a larger stack. This doesn't apply to you.
Instead, you need to change from a recursive approach to an iterative one. Most of the time, this isn't very hard thought it can be fiddly. Instead of calling itself again, the method uses a loop. For example, consider the classic teaching-example of a factorial method:
private static int Fac(int n)
{
return n <= 1 ? 1 : n * Fac(n - 1);
}
Instead of using recursion we loop in the same method:
private static int Fac(int n)
{
int ret = 1;
for(int i = 1; i <= n, ++i)
ret *= i;
return ret;
}
You can see why there's less stack space here. The iterative version will also be faster 99% of the time. Now, imagine we accidentally call Fac(n) in the first, and leave out the ++i in the second - the equivalent bug in each, and it causes an SOE in the first and a program that never stops in the second.
For the sort of code you're talking about, where you keep producing more and more results as you go based on previous results, you can place the results you've got in a data-structure (Queue<T> and Stack<T> both serve well for a lot of cases) so the code becomes something like):
private void MyLoadMethod(string firstConceptCKI)
{
Queue<string> pendingItems = new Queue<string>();
pendingItems.Enqueue(firstConceptCKI);
while(pendingItems.Count != 0)
{
string conceptCKI = pendingItems.Dequeue();
// make some script calls to DB, so that moTargetConceptList2 will have Concept-Relations for the current node.
// when this is zero, it means its a leaf.
int numberofKids = moTargetConceptList2.ConceptReltns.Count();
for (int i = 1; i <= numberofKids; i++)
{
oUCMRConceptReltn = moTargetConceptList2.ConceptReltns.get_ItemByIndex(i, false);
//Get the concept linked to the relation concept
if (oUCMRConceptReltn.SourceCKI == sConceptCKI)
{
oConcept = moTargetConceptList2.ItemByKeyConceptCKI(oUCMRConceptReltn.TargetCKI, false);
}
else
{
oConcept = moTargetConceptList2.ItemByKeyConceptCKI(oUCMRConceptReltn.SourceCKI, false);
}
//builder.AppendLine("\t" + oConcept.PrimaryCTerm.SourceString);
Debug.WriteLine(oConcept.PrimaryCTerm.SourceString);
pendingItems.Enque(oConcept.ConceptCKI);
}
}
}
(I haven't completely checked this, just added the queuing instead of recursing to the code in your question).
This should then do more or less the same as your code, but iteratively. Hopefully that means it'll work. Note that there is a possible infinite loop in this code if the data you are retrieving has a loop. In that case this code will throw an exception when it fills the queue with far too much stuff to cope. You can either debug the source data, or use a HashSet to avoid enqueuing items that have already been processed.
Edit: Better add how to use a HashSet to catch duplicates. First set up a HashSet, this could just be:
HashSet<string> seen = new HashSet<string>();
Or if the strings are used case-insensitively, you'd be better with:
HashSet<string> seen = new HashSet<string>(StringComparison.InvariantCultureIgnoreCase) // or StringComparison.CurrentCultureIgnoreCase if that's closer to how the string is used in the rest of the code.
Then before you go to use the string (or perhaps before you go to add it to the queue, you have one of the following:
If duplicate strings shouldn't happen:
if(!seen.Add(conceptCKI))
throw new InvalidOperationException("Attempt to use \" + conceptCKI + "\" which was already seen.");
Or if duplicate strings are valid, and we just want to skip performing the second call:
if(!seen.Add(conceptCKI))
continue;//skip rest of loop, and move on to the next one.
I think you have a recursion's ring (infinite recursion), not a really stack overflow error. If you are got more memory for stack - you will get the overflow error too.
For test it:
Declare a global variable for storing a operable objects:
private Dictionary<int,object> _operableIds = new Dictionary<int,object>();
...
private void Start()
{
_operableIds.Clear();
Recurtion(start_id);
}
...
private void Recurtion(int object_id)
{
if(_operableIds.ContainsKey(object_id))
throw new Exception("Have a ring!");
else
_operableIds.Add(object_id, null/*or object*/);
...
Recurtion(other_id)
...
_operableIds.Remove(object_id);
}
I break the code of the for loop without using break like I have for loop given below.And when i is 1 or 2 or 3 or any else but if condition is true then loop will be terminated because i will be 5 if the condition is true.And so NO need of break is needed there.Beacause I do not want to use break.I have done like this here.It works.
int myCondition=0;
bool flag=false;
for(int i=0;i<5;i++)
{
if(myCondition==0)
{
flag=true;
}
if(flag)
i=5;
}
But now I want to use foreach loop and in this loop when some condition is true then I want to break the foreach loop code.So what should I do here for breaking the foreach loop code without using break ? Like in the above for loop I have initialize i to 5 when condition is true.In the foreach loop anything like that to do to avoid break.
You should use what's in the language. There's no need to avoid break - just use it. Or to put it another way, "I don't want to use break" is not a good enough justification: if you think you've got a really good reason not to use it, then you should explain that reason. Don't hobble yourself by pretending perfectly reasonable features don't exist, and coming up with convoluted schemes to avoid them.
Don't do it.
Your manipulation of 'i' in the for loop is questionable already. Trying to mess with the iterator in a foreach-loop would be downright dirty. If it compiles at all.
I would write your example with a break or as:
bool myCondition=false;
for(int i=0;i<5 && !myCondition;i++)
{
....
}
In a foreach loop, when you're done before the entire sequence is complete, just call break
This is probably going to get me downvoted... but you should use the break keyword.
Failing that:
foreach(var foo in bar)
{
if(condition)
{
//perform normal loop code
//set condition if required.
}
//otherwise do nothing - the loop will iterate all the way to the end without
//doing anything.
}
You could be more expressive and use if(condition){ /*blah*/}else { continue; } inside the loop - but either way it does the same thing.
You can't do much else to break out of a for each other than:
Use break
Throw an Exception
In general, the 'pattern' you describe here is a code smell. It is NOT a good idea to change the index variable in a for-loop. It can result in unreadable, hard-to-maintain code, especially if the loop grows large.
That being said, why would you not want to use the break keyword. It is meant for this purpose, and whatever downside it has (in your opinion) is still a far better solution than the one you describe here.
Last, I see no way to do the same thing using a foreach loop in a sensible way.
Not using break in your for(;;) loop is a serious stylistic mistake. But you'll get away with it. But not when you use foreach, you have to use the break keyword.
Pay attention to the title of this blog post.
Well, thats why there is this comand "break". I have no reasons why shouldnt you use it.
Your code should absolutely be:
bool myCondition = false;
for(int i=0;i<5;i++)
{
// do stuff
if(myCondition)
break;
}
Not only are you using the commands (i.e. tools) provided by the language, but you are keeping the code very readable, and maintainable. The break command is fundamental to the language.
Trying to come up with some reason not to use break is like doing math on a calculator -- literally, turn the calculator over, get a silver paint marker, and do some math. You are crippling yourself by not using the tools in front of you.
The question field is a bit too short to pose my real question. If anyone can recapitulate it better, please feel free.
My real question is this: I'm reading a lot of other people's code in C# these days, and I have noticed that one particular form of iteration is widely spread, (see in code).
My first question is:
Are all these iterations equivalent?
And my second is: why prefer the first? Has it something to do with readibility? Now I don't believe the first form is more readable then the for-form once you get used to it, and readibility is far too much a subjective item in these constructs, of course, what you use the most will seem more readable, but I can assure everyone that the for-form is at least as readable, since it has all in one line, and you can even read the initializing in the construct.
Thus the second question: why is the 3rd form seen much less in code?
// the 'widespread' construct
int nr = getNumber();
while (NotZero(nr))
{
Console.Write(1/nr);
nr = getNumber();
}
// the somewhat shorter form
int nr;
while (NotZero(nr = getNumber()))
Console.Write(1 / nr);
// the for - form
for (int nr = getNumber(); NotZero(nr); nr = getNumber())
Console.Write(1 / nr);
The first and third forms you've shown repeat the call to GetNumber. I prefer the second form, although it has the disadvantage of using a side-effect within a condition of course. However I pretty much only do that with a while loop. Usually I don't end up passing the result as an argument though - the common situations I find myself in are:
string line;
while ( (line = reader.ReadLine()) != null)
...
and
int bytesRead;
while ( (bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
...
Both of these are now so idiomatic to me that they don't cause me any problems - and as I say, they allow me to only state each piece of logic once.
If you don't like the variable having too much scope, you can just introduce an extra block:
{
int bytesRead;
while ( (bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
// Body
}
}
Personally I don't tend to do this - the "too-wide" scope doesn't bother me that much.
I suspect it wouldn't be too hard to write a method to encapsulate all of this. Something like:
ForEach(() => reader.ReadLine(), // Way to obtain a value
line => line != null, // Condition
line =>
{
// body
};
Mind you, for line reading I have a class which helps:
foreach (string line in new LineReader(file))
{
// body
}
(It doesn't just work with files - it's pretty flexible.)
Are all this iterations equivalents?
yes
why prefer the first? Has it sth. to do with readibility?
because you may want to extend the scope of the nr var beyond the while loop?
why is the 3th form seen much less in code?
it is equivalent, same statements!
You may prefer the latter because you don't want to extend the scope of the nr variable
I think that the third form (for-loop) is the best of these alternatives, because it puts things into the right scope. On the other hand, having to repeat the call to getNumber() is a bit awkward, too.
Generally, I think that explicit looping is widely overused. High-level languages should provide mapping, filtering, and reducing. When these high level constructs are applicable and available, looping instead is like using goto instead of looping.
If mapping, filtering, or reducing is not applicable, I would perhaps write a little macro for this kind of loop (C# doesn't have those, though, does it?).
I offer another alternative
foreach (var x in InitInfinite(() => GetNumber()).TakeWhile(NotZero))
{
Console.WriteLine(1.0/x);
}
where InitInfinite is a trivial helper function. Whole program:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static IEnumerable<T> InitInfinite<T>(Func<T> f)
{
while (true)
{
yield return f();
}
}
static int N = 5;
static int GetNumber()
{
N--;
return N;
}
static bool NotZero(int n) { return n != 0; }
static void Main(string[] args)
{
foreach (var x in InitInfinite(() => GetNumber()).TakeWhile(NotZero))
{
Console.WriteLine(1.0/x);
}
}
}
I think people use the while() loop often because it best represents the way you would visualize the task in your head. I think think there is any performance benefits for using it over any other loop structure.
Here is a random speculation:
When I write C# code, the only two looping constructs I write are while() and foreach(). That is, no one uses 'for' any more, since 'foreach' often works and is often superior. (This is an overgeneralization, but it has a core of truth.) As a result, my brain has to strain to read any 'for' loop because it's unfamiliar.
As for why (1) and (2) are "preferred" over (3), my feeling is that most people think of the latter as a way to iterate over a range, using the condition to define the range, rather than continuing to iterate over a block while some condition still holds. The keyword semantics lend themselves to this interpretation and I suspect that, partly because of that, people find that the expressions are most readable in that context. For instance, I would never use (1) or (2) to iterate over a range, though I could.
Between (1) and (2), I'm torn. I used to use (2) (in C) most often due to the compactness, but now (in C#) I generally write (1). I suppose that I've come to value readability over compactness and (1) seems easier to parse quickly and thus more readable to my mind even though I do end up repeating a small amount of logic.
Honestly, I rarely write while statements anymore, typically using foreach -- or LINQ -- in the cases where while statements would previously been used. Come to think of it, I'm not sure I use many for statements, either, except in unit tests where I'm generating some fixed number of a test object.