多线程逻辑问题

时间:2013-09-21 14:16:35

标签: c# multithreading network-programming

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

这里我在这节课中有三种方法。

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

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

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

0 个答案:

没有答案