0

ブラウザとウェブサーバーの間でキャッシュを実行し、プロキシサーバーとして機能する次のクラスがあります。簡単なクラス定義だけを与えました。

ここで、このクラスには 3 つのメソッドがあります。

  1. RequestNewCacheFilePath は、ネットワーク ファイルをディスクに保存するために使用される一意の ID (関数呼び出しごとに 1 ずつ増加) を返します。

  2. 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);
        }
    }
}
4

0 に答える 0