Although running a parallel foreach that makes async calls is a pretty usual thing, I found my self in a very complicated situation, when async delegate calls got in the way!
The following gist file, is a basic structure of what I was trying to do: Ask
MemoryCacheManager for an item with
AddOrGetExisting by passing a
key to find the object and a generic delegate Func
task that actually returns the object.
Since this is not thread safe, my first approach was to use the lock statement, and as a countermeasure for not being able to have awaitable calls inside a lock, I played around with
Task.GetAwaiter().GetResult(). Ugly :/
Sychronous block on an asycrhonous task (that could be intensive) is never a good idea.
As Stephen Cleary states in his blog:
The code … will synchronously block until the task completes. As such, it is subject to the same old deadlock problems as Wait and Result…
“GetResult” actually means “check the task for errors”…
Finally, I found a better approach after reading a few things about thread sycrhonization. I end up with the following solution that uses a semaphore slim:
* As you can see, there are two
_cache.Get(key), a pattern that is called double-check locking. In short, locks are expensive and there is no reason to get one, if the requested object exists in the cache. Read more about that here and here