Caching things between execution runs (but same linqpad process, same open tab)?
There are times when I want to fetch something expensive and want to keep it around in memory between execution runs, ideally have it still look/feel like a local variable (var foo = GetStuff() in a 'C# Statements' run). In such a scenario I'm really looking for more of a REPL-like environment I guess (like VS's Immediate Window or PowerShell) instead of the 'run then throw away the results' that seems to happen now.
It seems like there's at least a few somewhat-painful-but-obvious options, including trying to (de)serialize the object graph between runs, or forcing it to preserve the app domains and then trying to make a static variable in some class to hold the graph between runs or the like.
Since it seems like this is something others have likely already run across and dealt with themselves, though, I'm guessing (well, hoping!) there's already a better answer out there that I just haven't found yet.
Any recommendations/ideas/pointers?
It seems like there's at least a few somewhat-painful-but-obvious options, including trying to (de)serialize the object graph between runs, or forcing it to preserve the app domains and then trying to make a static variable in some class to hold the graph between runs or the like.
Since it seems like this is something others have likely already run across and dealt with themselves, though, I'm guessing (well, hoping!) there's already a better answer out there that I just haven't found yet.
Any recommendations/ideas/pointers?
Comments
Most of the time if it's too painful to keep regenerating/refetch the data (for instance, trying to do 'ad-hoc' analysis over something like a remote web service that takes multiple minutes and returns lots of data), I just switch over to PowerShell and just deal with it there, but I really miss having the environment of LINQPad, specifically getting to write C# with intellisense.
I could likely export it out to Excel and do the analysis there, but 1) I'm slower there than in LINQPad and 2) often the first chunks of analysis aren't fetching all the data, but instead doing things like getting counts grouped by certain criteria, which is much faster doing via SQL than fetching all the data.
I may just need to bite the bullet and get better at Excel (and maybe learn PowerPivot), but it'd be nice to be able to keep 'expensive' data/objects around in memory instead of having them thrown out.
Since Roslyn already includes a REPL sample with it, I was hoping that maybe LINQPad could enable it if Roslyn is around - not sure if it's something that could be 'added on' without changing LINQPad (I couldn't think of how, at least
The difficulty is in typing the data. For example, if the result of your query was an IQueryable of an anonymous type, you'd want to somehow get the result back so it was typed as such so you can queries over it in subsequent runs.
Go to the "My Extensions" query and define this method: Usage: This will retrieve the customers from the database only on the first run.
Here are the limitations:
- It works only for IQueryable or lazily-evaluated IEnumerable sequences
- The element type T must be "stable" (in other words, it must not get recompiled between query runs). So it can be a CLR type, a type from a typed datacontext, or a custom type that you define in My Extensions or any assembly that you reference. Anonymous types will NOT work because they're different each time you compile. Tuples are OK.
Also note that LINQPad sometimes recycles app domains for performance and other reasons. You can avoid this by going to Edit | Preferences | Advanced and checking "Always Preserve Application Domains".
You can force LINQPad to clear the cache by pressing Shift+Control+F5.
www.linqpad.net/beta.aspx
(hopefully that comes across as complimentary correctly