ブラウザとウェブサーバーの間でキャッシュを実行し、プロキシサーバーとして機能する次のクラスがあります。簡単なクラス定義だけを与えました。
ここで、このクラスには 3 つのメソッドがあります。
RequestNewCacheFilePath は、ネットワーク ファイルをディスクに保存するために使用される一意の ID (関数呼び出しごとに 1 ずつ増加) を返します。
CommitNewCacheFilePath は、ファイルのダウンロード後に一意の ID を辞書にコミットします。ダウンロードするまで、その ID はディクショナリで 0 になります。
RequestNewCacheFilePath 関数では、値 0 で 1 つのディクショナリ項目が追加されました。これは、そのリソースのリソース ダウンロードが進行中であることを意味します。ファイルのダウンロードが完了すると、辞書は実際の一意のキャッシュ ID で更新されます。ただし、マルチスレッド シナリオでは、CommitNewCacheFilePath 関数のデバッグ アサーションが失敗することがあります。
public class CacheManager
{
const string INDEX_FILE_NAME = "index.txt";
Dictionary<string, int> _dictResources = new Dictionary<string, int>();
public IAppServer Server { get; private set; }
object _syncCacheIdObject = new object();
int _cacheId;
public string CacheDirectoryPath { get; private set; }
public CacheManager(IAppServer server)
{
server.ThrowIfNull("server");
Server = server;
CacheDirectoryPath = (server.Config as ProxyServerConfig).CacheDirectoryPath;
if (CacheDirectoryPath.IsEmpty())
CacheDirectoryPath = Path.Combine("C:\\", Application.ProductName);
if (!Directory.Exists(CacheDirectoryPath))
Directory.CreateDirectory(CacheDirectoryPath);
}
public int GetCacheId(string key)
{
int value;
if (_dictResources.TryGetValue(key, out value))
return value;
else
return -1;
}
public string RequestNewCacheFilePath(string key)
{
int cacheId;
lock (_syncCacheIdObject)
{
cacheId = ++_cacheId;
}
lock (_dictResources)
{
if (_dictResources.ContainsKey(key))
return null;
else
{
_dictResources[key] = 0;
return Path.Combine(CacheDirectoryPath, cacheId + ".cache");
}
}
}
public void CommitNewCacheFilePath(string key, string cachedFilePath)
{
int cachedId = int.Parse(Path.GetFileNameWithoutExtension(cachedFilePath));
lock (_dictResources)
{
Debug.Assert(_dictResources[key] == 0);
_dictResources[key] = cachedId;
}
}
public void RevertNewCacheFilePath(string resourcePath)
{
lock (_dictResources)
{
_dictResources.Remove(resourcePath);
}
}
}