Middle · Trace · HybridCache coordination

Execution context: this is the complete portable .NET9 console companion, using ordinary BCL code. Trace its exact stdout and justify each state or comparison; it does not start the external ASP.NET server or SQL database.

Think through your answer before opening the explanation.

Production engineering

using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

var result=new TaskCompletionSource<int>(); Task<int>? pending=null; int factories=0; Task<int> Get() { if(pending is null) { factories++; pending=result.Task; } return pending; }
var first=Get(); var second=Get(); Console.WriteLine("shared:"+ReferenceEquals(first,second)); result.SetResult(7); Console.WriteLine("total:"+((await first)+(await second))); Console.WriteLine("factories:"+factories);
Reveal answer and reasoning

The output lines, in order, are “shared:True”; “total:14”; “factories:1”. The portable .NET9 console companion uses a TaskCompletionSource and a nullable pending Task reference. The first serialized call to Get stores result.Task and increments factories; the second returns that same reference. ReferenceEquals therefore prints shared:True. Completing the source with seven makes both awaited results available, and adding them prints total:14, followed by factories:1.

These are actual BCL Task operations, but the null check is not synchronized and no concurrent threads race through Get. The program has no HybridCache, HTTP server, cache expiration or SQL provider. Its purpose is to make shared ownership visible before inspecting the external implementation.

The package documents that factory cancellation reflects all callers abandoning the shared operation; canceling one waiter is a different event from canceling every participant. Distinct keys can legitimately start distinct factories. Other HybridCache instances, including instances in another process, do not inherit this owner's coordination even if a secondary store were shared. Neither a one-minute expiration nor RemoveAsync makes source data and cached data one transaction.

The sample's ordinary Task companion is even narrower: it assumes serialized access and never retries a failed or canceled pending task. Keep each limitation attached to the component that actually owns it.

What a strong answer covers

  • Exact output: shared:True | total:14 | factories:1
  • The portable .NET9 console companion uses a TaskCompletionSource and a nullable pending Task reference.
  • The package documents that factory cancellation reflects all callers abandoning the shared operation; canceling one waiter is a different event from canceling every participant.

Common pitfall

The package documents that factory cancellation reflects all callers abandoning the shared operation; canceling one waiter is a different event from canceling every participant. Distinct keys can legitimately start distinct factories. Other HybridCache instances, including instances in another process, do not inherit this owner's coordination even if a secondary store were shared. Neither a one-minute expiration nor RemoveAsync makes source data and cached data one transaction. The sample's ordinary Task companion is even narrower: it assumes serialized access and never retries a failed or canceled pending task. Keep each limitation attached to the component that actually owns it.

Follow-up questions

  1. How would a stream of unique cache keys defeat same-key coalescing, and where would you place a separate source-work budget?
  2. Why can a later clean cache reset produce generation2 without proving that the previous miss ran two factories?

Self-review

Choose what to revisit. These marks are your own assessment and are separate from lesson completion.

Primary references

Open lesson and code ↗

← All interview questions