You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
publicclassExpiringCache{privateConcurrentDictionary<SocketAddress,(IPEndPointendpoint,DateTimelastAccess)>_cache;privateTimeSpan_expirationTime;privatereadonlyTimer_cleanupTimer;publicExpiringCache(TimeSpanexpirationTime){_cache=newConcurrentDictionary<SocketAddress,(IPEndPoint,DateTime)>();_expirationTime=expirationTime;_cleanupTimer=newTimer(Cleanup,null,_expirationTime,_expirationTime);}publicIPEndPointAddOrUpdateEndPoint(SocketAddressaddress){varnow=DateTime.UtcNow;// Check if the SocketAddress key already existsif(!_cache.TryGetValue(address,outvarcacheEntry)){Console.WriteLine($"New client added.");// Create new IPEndPoint from SocketAddressvarendpoint=newIPEndPoint(IPAddress.Any,0);endpoint=(IPEndPoint)endpoint.Create(address);// Add to cachecacheEntry=(endpoint,now);_cache[address]=cacheEntry;}else{// Update last access time for existing entryConsole.WriteLine($"Existing client activity updated.");cacheEntry=(cacheEntry.endpoint,now);_cache[address]=cacheEntry;}returncacheEntry.endpoint;}privatevoidCleanup(objectstate){Console.WriteLine($"Performing client cleanup.");varnow=DateTime.UtcNow;foreach(varkvpin_cache){if(now-kvp.Value.lastAccess>_expirationTime){// Remove old entriesConsole.WriteLine($"Client removed for inactivity.");_cache.TryRemove(kvp.Key,out_);}}}}
The text was updated successfully, but these errors were encountered:
Make sure to clone the SocketAddress when you insert it as a key into the dictionary; I made this mistake originally, and put the same instance into the dictionary, meaning the addresses would always be equal.
Don't write to console, certainly not in the successful lookup case, that will lock on the console and generally ruin the performance.
Because the entry in the dictionary is a struct, you should consider using CollectionsMarshal.GetValueRefOrNullRef to get a reference to the value type inside the dictionary, rather than needing to copy the value in and out of the dictionary when you update the time.
Don't use DateTime.UtcNow to update; DateTime.UtcNow is relatively slow compared to something like Environment.TickCount64:
Because you only compare about relative time rather than absolute time, you can save a bunch of CPU cycles by using TickCount64, and store the long instead of the DateTime.
There's no explicit disposal on this class to stop the Timer from running.
Fixed your dictionary issue:
The text was updated successfully, but these errors were encountered: