0

我有以下类在浏览器和网络服务器之间执行缓存并用作代理服务器。我只给出了简单的类定义。

在这个类中,我有三种方法。

  1. RequestNewCacheFilePath 返回唯一的 id(每次函数调用后递增 1),用于将网络文件保存到磁盘。

  2. CommitNewCacheFilePath 在文件下载后将唯一 id 提交到字典中。直到下载它的 id 将是 0 到字典中。

在 RequestNewCacheFilePath 函数中,添加了一个值为 0 的字典项。这意味着正在为该资源下载资源。当文件下载完成时,字典会使用其实际唯一的缓存 ID 进行更新。但有时In 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