.Net, IEnumerable, and caching

puffpio

Golden Member
Dec 21, 1999
1,664
0
0
If you add an IEnumerable object into a cache (ASP.net cache) will it enumerate the objects and stick it in there?

for example if I have this method psuedocode

IEnumerable<int> getInts()
{
// open DB connection
// execute stored procedure
while (mySqlDataReader.next())
{
yield return mySqlDataReader.getInt();
}
//close db connection
}


and i add whatever returns from that into a cache..what happens? does the entire thing get enumerated so the sql connection can close..or something else?


A similar question, if the IEnumerable<int> is serialized..what happens?
 

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net
Syntactic shortcuts like yield tend to confuse what's actually going on. The result of a call to getInts() is an object that implements IEnumerable. If you place the return value from getInts() into the cache, then you will be caching that collection object, whatever it is. The cache will not iterate through that collection, and wouldn't have any reason to.

If you use getInts in a foreach() statement, then GetEnumerator() would be called on the returned IEnumerable reference, resulting in an object that implements IEnumerator, and its methods would then be used to traverse the collection. You could then cache each returned value from the IEnumerator.Current property, but I can't see the cache doing that for you.
 

imported_Dhaval00

Senior member
Jul 23, 2004
573
0
0
I know this post is pretty much analogous to thread-hijacking, and even though I haven't posted in while, I must say... doing the following is usually a recipe for disaster!

IEnumerable<int> getInts()
{
// open DB connection
// execute stored procedure
while (mySqlDataReader.next())
{
yield return mySqlDataReader.getInt();
}
//close db connection
}

You're going to yield to an external entity the contents of an open SQLDataReader?
 
Oct 27, 2007
17,009
5
0
I could be wrong here, but I think yield will cause the CLR to create a new object that is not bound to the DB. It can't return the actual object because it's not really "returning" in the true sense of the word, and that object could still be required in the stack frame. Please correct me if I'm wrong.
 

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net
It caught my eye too, Dhaval. I'm not sure whether it introduces vulnerability, but I probably wouldn't do it.
 

imported_Dhaval00

Senior member
Jul 23, 2004
573
0
0
Well, the issue is that the SqlDataReader is a forward-read-only object which keeps the connection to the DB open while the list of items is being iterated over. yield return pauses the method execution and the next time you call it (for the next enumeration value), the method will continue to execute from the last yield return call - which essentially means that the underlying connection to the DB will be kept open unnecessarily.


Originally posted by: GodlessAstronomer
I could be wrong here, but I think yield will cause the CLR to create a new object that is not bound to the DB. It can't return the actual object because it's not really "returning" in the true sense of the word, and that object could still be required in the stack frame.

What's your reasoning for this statement? I am just asking because chances are I could be wrong. Basically, the way I understand it is at compile-time the yield keyword is transformed into a fancied "get" method (similar to a read-only property). "yield return," in essence, yields to the client - which is also the reason why you can't modify items in a foreach loop - if you try, CLR will throw an exception under the contract that "the host is yielding an object for your reading purposes only, you better not mess with the object in any way."
 

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net
Here's an interesting, though not very readable discussion on the semantics of yield:

http://bytes.com/groups/net-c/...cification-enumeration

I agree with the first poster in that thread. Yield is a horrible, gross hack. Based on what little I can find about its actual semantics probably the best way to think of it is that it suspends execution of the current loop, and boxes the current object into an enumerator, and calls back into the consumer, thereby preserving the stack frame in which yield was evaluated so that it can be restarted to get the next object. The compiler generates all this shit so that people don't have to explicitly implement IEnumerable. I don't see any reason to think it will close the database connection before the enumeration has completed (yield break or the function returns).

There are things about C# that bug the crap out of me, and one of them is this steady, lamentable trend toward layering up gob after gob of syntactic sugar to try and make the framework easier to use. Yield is a prime example, as are anonymous delegates.
 

imported_Dhaval00

Senior member
Jul 23, 2004
573
0
0
IMO, once you get the hang of them, anonymous delegates can be super-powerful. Of course, other people need to understand the syntax, too, but I think that is just an excuse to impinge on older ways of doing things. I have put anonymous delegates to some real good use, especially in places where I see it is easier to use them - for example, why should I be declaring class level properties and creating extra methods when I can write an inline delegate to access ambient (method-scope) variables? A couple of recent projects (WPF and WCF, primarily), the team and I have used them heavily and to good use, too.

For example one of the WPF applications that we're working on right now has a generic host which controls the workflow (flow of different client-specific Window objects). The following are excerpts from one of the client Window objects... see if you can pinpoint the use of anonymous delegates (hopefully, you'll see the usefulness):
http://rafb.net/p/XhrIP798.html

I guess I am pointing to this because, just like anonymous delegates, the yield keyword has its own usefulness - if you've ever worked with API's/SDK's which use collections heavily, you can pretty much fall in love (I know sounds dorky) with the yield keyword. Yielding from within the scope of an open SqlDataReader is definitely not a way to use the keyword.

Edit: Sorry, messed up the code-post.
Secod Edit: I didn't want to sound too abrasive (I just re-read the post), but am posting this in a hurry, guys... so hopefully, you guys will filter the info in the post and ignore the opinions :).
 

JasonCoder

Golden Member
Feb 23, 2005
1,893
1
81
I think there is some confusion with the yield statement in this thread. Yield is some "syntactic sugar" that helps with iterators. Iterators are just a way to return an IEnumerable, IEnumerable<T>, IEnumerator or IEnumerator<T> without having to write the code yourself.

When the CLR hits a yield statement, it returns immediately but the place in the method is "saved" so that the next foreach pass of the caller picks up where it left off. Yield statements are awesome. You don't have to create the collection or implement the interface, the compiler does it for you.

Using yield statements whilst iterating a datareader is tricky. Obviously you don't want to keep a datareader open any longer than absolutely necessary. Cache the reader results and then provide an iterator over that.

Hope this clears things up. Iterators are great things.
 

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net
Iterators are great things, but iterators and yield statements are not the same thing. Yield is a shortcut method for implementing iterators, similar to the way that automatic properties are shortcut method for implementing getters and setters.

My problem with yield is simple: iterators can be made easier to use through abstraction and well-designed framework classes. Cluttering up a language with multiple means of accomplishing the same thing just bugs me. I like languages to be as minimal and cohesive as possible, while remaining expressive. I hated watching C++ balloon from maybe 35 keywords to over... 60 I think by the time the standards committee was through ministering to it, and I hate seeing C# bulk up too.
 

JasonCoder

Golden Member
Feb 23, 2005
1,893
1
81
Don't know what I was thinking in my original post regarding datareaders. I revised my post.