Weird exception...

cbreemer

Well-known member
Joined
Dec 1, 2021
Messages
188
Programming Experience
10+
Just wondering if anyone has ever experienced the exception in the below image. It came out of the blue, in a piece of code that has always worked, and on a line that you would never expect to run into such a problem. I wasn't aware of anything special happening at the time. I haven't changed anything, and the exception hasn't occurred since. Weird, isn't it ?

exception.jpg
 
EnumerateFiles() is implemented as a lazy method. It doesn't actually performs the operation of getting items until you ask for them. Unfortunately using Count() will force it to enumerate all the items. If you have a lot of files, or if the drive is slow, or if you have AV software that is slow, or if there are other processes competing for CPU, bus, or disk IO, then that exception if entirely plausible. That exception is there to prevent the enumeration from completely blocking your app forever.

Do you really need the count ahead of time? Or can you just learm what the count is as you progress through enumerating items?
 
Thanks, that is really useful ! Although this is not the .Net EnumerateFiles() but the one from the 3rd party MediaDevices package it surely works the same, because EnumerateFiles() returns instantly but Count() takes almost 20 seconds 😲 whereas I had expected it to be the other way around. Strange that neither man page mentions this lazyness, and that the man page for List<T>.Count does not mention the possibility of an exception. Regardless, I would have expected a higher level exception such as 'Operation timed out'. But I may well be expecting too much 🙂

I wanted the total count of files in order to display a progress bar while downloading them all which is quite a lengthy process (since some update to Windows or Android mucked it up, previously it was fine).

BTW - I now see that I am using Count() instead of Count. And it works, despite Count() not been listen as a method of List<T>. Is it perhaps a rule in C# that you can access a property as if it were a method ? Do I perhaps get this exception just because I'm calling a method ?
 
Last edited:
Enumerable.Count method is a Linq extension for all enumerables (including arrays and lists). List<T> also has defined a Count property. Arrays have a Length property.

Read the Remarks section here about how Enumerate works: Directory.EnumerateFiles Method (System.IO)
Also notice it returns IEnumerable<String> instead of String array like GetFiles method.
 
Enumerable.Count method is a Linq extension for all enumerables (including arrays and lists). List<T> also has defined a Count property. Arrays have a Length property.

Read the Remarks section here about how Enumerate works: Directory.EnumerateFiles Method (System.IO)
Also notice it returns IEnumerable<String> instead of String array like GetFiles method.
Thanks John. I admit finding it confusing in some cases when (and why) something is a property or a method. Especially in a case like this where both are implemented.
 
Generally properties should return some kind of existing state of the object, while methods that return a value needs to do some work in order to get/compute that value.

Properties should also return same value for each call if nothing else about the object is changed, while methods may return different results just by being called at different times (or given different arguments.)
 
Especially in a case like this where both are implemented.
They're implemented on different types though, so they are different members. The List<T>.Count property is implemented specifically for that type. It will be getting a value stored within the object and not actually have to count the items each time you get it. The Enumerable.Count method can be called on any IEnumerable<T> so it may have to count the items by enumerating the object. As @JohnH said, the property gets an existing state value while the method does work to determine the result. In a case like this, you should use the type-specific member preferentially because it is almost certainly guaranteed to be more efficient. That said, I would not be surprised to learn that Enumerable.Count checks whether the object is an ICollection<T> first and, if it is, uses it's Count property.
 
They're implemented on different types though, so they are different members. The List<T>.Count property is implemented specifically for that type. It will be getting a value stored within the object and not actually have to count the items each time you get it. The Enumerable.Count method can be called on any IEnumerable<T> so it may have to count the items by enumerating the object. As @JohnH said, the property gets an existing state value while the method does work to determine the result. In a case like this, you should use the type-specific member preferentially because it is almost certainly guaranteed to be more efficient. That said, I would not be surprised to learn that Enumerable.Count checks whether the object is an ICollection<T> first and, if it is, uses it's Count property.
Thank you !! All replies in this thread have been very useful, but this one made the penny drop at last ! I feel real stupid now for assuming that EnumerateFiles was returning a List, and blindly deducing that both Count and Count() could be used. Had I looked a bit better, I should have realized I was dealing with an interface rather than a class. This explains everything ! Except that enumeration is so excruciatingly slow... but I'm convinced this is not caused by C# or .Net. It used to work fine until one day it suddenly was down to a slow grind. I could not find anything about it though. Interestingly, when I do the enumeration a second time, it completes almost instantly. Even after I terminate and re-run the program. It's only the first time after I (re)connect my phone that it's so slow. Looks like there's some persistent caching going on.
 
Back
Top Bottom