tgoop.com/csharp_1001_notes/680
Last Update:
π ΠΠ°Π΄Π°ΡΠ°: "ΠΡΡΠΎΠΊΠΎΠ½Π°Π³ΡΡΠΆΡΠ½Π½ΡΠΉ ΠΊΡΡ Ρ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠΉ ΠΎΡΠΈΡΡΠΊΠΎΠΉ ΠΈ ΠΊΠΎΠ½ΠΊΡΡΠ΅Π½ΡΠ½ΡΠΌ Π΄ΠΎΡΡΡΠΏΠΎΠΌ"
βοΈΠ£ΡΠ»ΠΎΠ²ΠΈΠ΅:
Π Π΅Π°Π»ΠΈΠ·ΡΠΉΡΠ΅ ΠΊΠ»Π°ΡΡ SmartCache<TKey, TValue>
Π² .NET, ΠΊΠΎΡΠΎΡΡΠΉ Π΄ΠΎΠ»ΠΆΠ΅Π½:
- ΠΠΎΠ·Π²ΠΎΠ»ΡΡΡ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ ΠΈ ΠΏΠΎΠ»ΡΡΠ°ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ ΠΈΠ· ΠΊΡΡΠ° Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΠΉ ΡΡΠ΅Π΄Π΅ (`Get`, `Set`).
- ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΡΠ΄Π°Π»ΡΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ ΡΠ΅ΡΠ΅Π· N ΡΠ΅ΠΊΡΠ½Π΄ ΠΏΠΎΡΠ»Π΅ ΠΈΡ
Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΡ (TTL).
- ΠΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ Π²ΡΡΠΎΠΊΡΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ ΠΏΡΠΈ ΠΌΠ°ΡΡΠΎΠ²ΠΎΠΌ Π΄ΠΎΡΡΡΠΏΠ΅ (ΡΡΡΡΡΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ Π² ΡΠ΅ΠΊΡΠ½Π΄Ρ).
- ΠΠΈΠ½ΠΈΠΌΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ (`lock`) ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π½Π΅Π±Π»ΠΎΠΊΠΈΡΡΡΡΠΈΠ΅ ΡΡΡΡΠΊΡΡΡΡ.
- ΠΠΎΡΡΠ΅ΠΊΡΠ½ΠΎ ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ ΠΈΡΡΠ΅ΠΊΡΠΈΠΌΠΈ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°ΠΌΠΈ:
- ΠΠ΅ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡ ΠΈΡ
ΡΠ΅ΡΠ΅Π· Get
.
- ΠΠ΅ ΠΊΠΎΠΏΠΈΡΡ ΠΌΡΡΠΎΡ Π² ΠΏΠ°ΠΌΡΡΠΈ.
---
βͺοΈ ΠΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ:
- ΠΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠ΅ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ .NET (`ConcurrentDictionary`, Timer
, Task
, CancellationToken
ΠΈ Ρ.Π΄.).
- ΠΠ΅Π»ΡΠ·Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π²Π½Π΅ΡΠ½ΠΈΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ ΡΠΈΠΏΠ° MemoryCache
, Redis
, LazyCache
ΠΈ Π΄Ρ.
- ΠΡΠΆΠ½ΠΎ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ ΡΠ°Π±ΠΎΡΡ ΠΏΠΎΠ΄ Π±ΠΎΠ»ΡΡΠΎΠΉ Π½Π°Π³ΡΡΠ·ΠΊΠΎΠΉ (ΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠ»ΡΡΠ΅ΠΉ ΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ ΠΏΠ°ΡΠ°Π»Π»Π΅Π»ΡΠ½ΠΎ).
---
βͺοΈ ΠΠΎΠ΄ΡΠΊΠ°Π·ΠΊΠΈ:
- ΠΠ»Ρ ΠΊΠΎΠ½ΠΊΡΡΠ΅Π½ΡΠ½ΠΎΠ³ΠΎ Π΄ΠΎΡΡΡΠΏΠ° ΠΏΠΎΠ΄ΠΎΠΉΠ΄ΡΡ ConcurrentDictionary<TKey, ValueWithExpiry>
.
- ΠΠ»Ρ ΠΎΡΠΈΡΡΠΊΠΈ ΡΡΡΠ°ΡΠ΅Π²ΡΠΈΡ
Π΄Π°Π½Π½ΡΡ
:
- ΠΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΎΠ½ΠΎΠ²ΡΡ Π·Π°Π΄Π°ΡΡ (`Task`) Ρ ΡΠ°ΠΉΠΌΠ΅ΡΠΎΠΌ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΠ΅ΡΠΈΠΎΠ΄ΠΈΡΠ΅ΡΠΊΠΈ ΡΠΈΡΡΠΈΡ ΡΡΠ°ΡΡΠ΅ Π·Π°ΠΏΠΈΡΠΈ.
- ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Π³ΠΎΠ½ΠΊΠΈ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΉ: ΠΌΠ΅ΠΆΠ΄Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΎΠΉ ΡΡΠΎΠΊΠ° ΠΆΠΈΠ·Π½ΠΈ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° ΠΈ Π΅Π³ΠΎ ΡΠ΄Π°Π»Π΅Π½ΠΈΠ΅ΠΌ.
---
βͺοΈ Π§ΡΠΎ ΠΎΡΠ΅Π½ΠΈΠ²Π°Π΅ΡΡΡ:
- Π£ΠΌΠ΅Π½ΠΈΠ΅ ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°ΡΡ ΠΏΠΎΡΠΎΠΊΠΎΠ±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΡΠ΅ ΡΡΡΡΠΊΡΡΡΡ Π΄Π°Π½Π½ΡΡ
.
- ΠΡΠΎΠ΄ΡΠΌΠ°Π½Π½ΠΎΡΡΡ Π±Π°Π»Π°Π½ΡΠΈΡΠΎΠ²ΠΊΠΈ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠΊΠΎΡΠΎΡΡΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ ΠΈ ΡΠ°ΡΡΠΎΡΠΎΠΉ ΠΎΡΠΈΡΡΠΊΠΈ.
- ΠΡΠ°Π²ΠΈΠ»ΡΠ½Π°Ρ ΡΠ°Π±ΠΎΡΠ° ΡΠΎ Π²ΡΠ΅ΠΌΠ΅Π½Π΅ΠΌ ΠΆΠΈΠ·Π½ΠΈ (`TTL`).
- Π§ΠΈΡΡΠΎΡΠ° ΠΈ Π»Π°ΠΊΠΎΠ½ΠΈΡΠ½ΠΎΡΡΡ ΠΊΠΎΠ΄Π°.
---
βͺοΈ Π Π°Π·Π±ΠΎΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠ³ΠΎ ΡΠ΅ΡΠ΅Π½ΠΈΡ:
βͺοΈ ΠΡΠ½ΠΎΠ²Π½Π°Ρ ΠΈΠ΄Π΅Ρ:
- Π ΠΊΡΡΠ΅ Ρ
ΡΠ°Π½ΠΈΠΌ Π½Π΅ ΠΏΡΠΎΡΡΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, Π° ΠΏΠ°ΡΡ (Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ + Π²ΡΠ΅ΠΌΡ ΠΈΡΡΠ΅ΡΠ΅Π½ΠΈΡ).
- ΠΡΠΈ Get(key)
:
- ΠΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ, ΠΈΡΡΡΠΊ Π»ΠΈ ΡΠ»Π΅ΠΌΠ΅Π½Ρ.
- ΠΡΠ»ΠΈ ΠΈΡΡΡΠΊ β ΡΠ΄Π°Π»ΡΠ΅ΠΌ Π΅Π³ΠΎ ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌ null
ΠΈΠ»ΠΈ default
.
- ΠΡΠΈ Set(key, value)
:
- Π‘ΠΎΡ
ΡΠ°Π½ΡΠ΅ΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Ρ ΡΠ΅ΠΊΡΡΠΈΠΌ Π²ΡΠ΅ΠΌΠ΅Π½Π΅ΠΌ + TTL.
- ΠΡΠ΄Π΅Π»ΡΠ½Π°Ρ ΡΠΎΠ½ΠΎΠ²Π°Ρ Π·Π°Π΄Π°ΡΠ° (`Task`) ΡΠ΅Π³ΡΠ»ΡΡΠ½ΠΎ ΡΠΊΠ°Π½ΠΈΡΡΠ΅Ρ ΠΊΡΡ ΠΈ ΡΠ΄Π°Π»ΡΠ΅Ρ ΡΡΡΠ°ΡΠ΅Π²ΡΠΈΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ.
βͺοΈ ΠΠΈΠ½ΠΈ-ΠΏΡΠΈΠΌΠ΅Ρ ΡΡΡΡΠΊΡΡΡΡ:
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
public class SmartCache<TKey, TValue>
{
private readonly ConcurrentDictionary<TKey, (TValue Value, DateTime Expiry)> _cache = new();
private readonly TimeSpan _ttl;
private readonly CancellationTokenSource _cts = new();
public SmartCache(TimeSpan ttl)
{
_ttl = ttl;
StartCleanupTask();
}
public void Set(TKey key, TValue value)
{
_cache[key] = (value, DateTime.UtcNow.Add(_ttl));
}
public TValue Get(TKey key)
{
if (_cache.TryGetValue(key, out var entry))
{
if (entry.Expiry > DateTime.UtcNow)
{
return entry.Value;
}
else
{
_cache.TryRemove(key, out _);
}
}
return default;
}
private void StartCleanupTask()
{
Task.Run(async () =>
{
while (!_cts.Token.IsCancellationRequested)
{
foreach (var key in _cache.Keys)
{
if (_cache.TryGetValue(key, out var entry) && entry.Expiry <= DateTime.UtcNow)
{
_cache.TryRemove(key, out _);
}
}
await Task.Delay(TimeSpan.FromSeconds(30), _cts.Token); // ΠΏΠ΅ΡΠΈΠΎΠ΄ΠΈΡΠ΅ΡΠΊΠ°Ρ ΠΎΡΠΈΡΡΠΊΠ°
}
});
}
public void Dispose()
{
_cts.Cancel();
}
}
π ΠΠ°ΠΆΠ½ΡΠ΅ ΠΌΠΎΠΌΠ΅Π½ΡΡ:
- ΠΡΡ ΠΊΠΎΠ½ΠΊΡΡΠ΅Π½ΡΠ½ΡΠΉ (`ConcurrentDictionary`) β Π΄ΠΎΡΡΡΠΏ Π±Π΅Π· ΡΠ²Π½ΡΡ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΎΠΊ.
- ΠΠ΅ΡΠΈΠΎΠ΄ΠΈΡΠ΅ΡΠΊΠ°Ρ ΡΠΈΡΡΠΊΠ° Π½Π΅ ΠΌΠ΅ΡΠ°Π΅Ρ ΠΎΡΠ½ΠΎΠ²Π½ΡΠΌ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡΠΌ.
- Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΈΡΡΡΠΊΡΠΈΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ "ΠΌΡΠ³ΠΊΠΎ" (ΡΠ΅ΡΠ΅Π· ΠΏΡΠΎΠ²Π΅ΡΠΊΡ ΡΡΠΎΠΊΠ° ΠΆΠΈΠ·Π½ΠΈ).
- Π€ΠΎΠ½ΠΎΠ²Π°Ρ Π·Π°Π΄Π°ΡΠ° ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎ Π·Π°Π²Π΅ΡΡΠ°Π΅ΡΡΡ ΡΠ΅ΡΠ΅Π·
CancellationToken
.BY C# 1001 notes
Share with your friend now:
tgoop.com/csharp_1001_notes/680