Unexpected LINQPad cache behavior when runtime type doesn't match compile time type
I have some long running queries I'm trying to utilize LINQPad's caching mechanisms with, but LINQPad is often crashing unexpectedly or ignoring the cache all together.
In this script, it's querying web apis (YouTube in my case) for some data and caching the responses. However when I update my script for some changes I need to make and rerun. I would always get an UncacheableObjectException
and need to rerun everything.
I tried to reproduce the problem and came up with the below script:
http://share.linqpad.net/gmjaev.linq
//#load "FooBar" void Main() { var cache = Util.Cache(() => GetFooBar()); //cache = cache; cache.Dump(); FooBar GetFooBar() { var returnValue = new FooBar(); Util.HorizontalRun(true, "recalculating cache:", returnValue).Dump(); return returnValue; } Foo GetFoo() { var returnValue = new FooBar(); Util.HorizontalRun(true, "recalculating cache:", returnValue).Dump(); return returnValue; } FooBar GetFooBar2() { var returnValue = new BooBar(); Util.HorizontalRun(true, "recalculating cache:", returnValue).Dump(); return returnValue; } } // Also contents of "FooBar.linq" [Serializable] public abstract record Foo(); [Serializable] public record FooBar() : Foo(); [Serializable] public record BooBar() : FooBar();
If you change the cache line to use the different GetFoo*()
methods, then run, then make a trivial change (toggle line 6), you'll see whether or not it's recalculating or not. With GetFooBar()
it will work as expected. GetFoo()
and GetFooBar2()
will always recalculate. And it doesn't seem to matter if the types are all defined in the script or in a #loaded script.
However in my script, I tried working around the caching error and tried caching differently (a dictionary) and still the same problem. However with the repro script, that triggers the UncacheableObjectException
. Changing the cache lines to this:
var cache = Util.Cache(() => new Dictionary<string, Foo>()); cache["foobar"] = GetFooBar(); // comment out and rerun
Comments
In my actual script, the cache lines are async and I was assuming it was the
Task
that was causing the problem.The types are:
Also tried switching things around to make it so I can keep the runtime and compile time types the same but still the same problem.
I've released a new beta that is more flexible with typing, and that also allows the caching of tasks. Note that I've not fully tested all scenarios for tasks whose result type is in the query. Let me know how you get on.
Not sure whether to bump or create a new topic, but it seems like this is is causing issue again. When you make a change to the script after the result is cached, certain values are not restored.
Run it once it will output what you expect, fromCache = false. Run again, same result, fromCache = true. Touch the file (add a space somewhere) and run, the
Type
value of the inner result is null, fromCache = true.Thanks - this is in fact a different issue. I'll flag it for the 8.4.x builds, most likely next week.
This should now be fixed in 8.4.1.