Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对路径的访问被拒绝互斥_C#_Asp.net_.net_Asp.net Mvc_Multithreading - Fatal编程技术网

C# 对路径的访问被拒绝互斥

C# 对路径的访问被拒绝互斥,c#,asp.net,.net,asp.net-mvc,multithreading,C#,Asp.net,.net,Asp.net Mvc,Multithreading,以下是我的方法: public static string CacheKey(string userName) { return "MyObj" + userName; } private static MyObj CachedObj(string userName) { string cacheKey = CacheKey(userName); M

以下是我的方法:

public static string CacheKey(string userName)
        {
            return "MyObj" + userName;
        }

private static MyObj CachedObj(string userName)
        {
            string cacheKey = CacheKey(userName);            

            MyObj cachedBW = HttpRuntime.Cache[cacheKey] as MyObj;
            if (cachedBW == null)
            {
                Mutex bwMutex = new Mutex(false, cacheKey);
                if (bwMutex.WaitOne(Constant.LOCKING_TIMEOUT))
                {
                    try
                    {
                        cachedBW = HttpRuntime.Cache[cacheKey] as MyObj;
                        if (cachedBW == null)
                        {
                            cachedBW = InitialisedBusinessWrapper();
                            HttpRuntime.Cache.Add(cacheKey, cachedBW, null,
                                System.Web.Caching.Cache.NoAbsoluteExpiration,
                                TimeSpan.FromMinutes(INACTIVITY_TIMEOUT), CacheItemPriority.Normal, null);
                            return cachedBW;
                        }
                        else
                            return cachedBW;
                    }
                    finally
                    {
                        bwMutex.ReleaseMutex();
                    }
                }
                else
                    throw new Exception("Timed out waiting");
            }
            else
                return cachedBW;

        }

我一次又一次地访问路径
MyObjUsername
,该路径是我的缓存密钥,但被拒绝。你觉得我的代码有问题吗?我该如何解决这个问题?这些方法在我的控制器的操作中被调用,特定的多个用户可以使用相同的用户名登录。

您需要锁定HttpRuntime.Cache对象,而不是密钥

HttpRuntime.Cache不是线程安全的

我更喜欢使用带锁的MemoryCache,因为MemoryCache不是线程安全的:


锁定键不能在静态方法中

此代码可以让您更轻松:

public static class WebCache
{
    #region Private Fields

    private static readonly MemoryCache _cache = MemoryCache.Default;

    private static readonly HashSet<string> _keysList = new HashSet<string>();

    private static readonly object _lock = new object();

    #endregion Private Fields

    #region Public Methods

    public static T GetUpdate<T>(string key, Func<T> getValue)
    {
        if (_cache[key] == null) { Update(key, getValue); }

        return (T)_cache[key];
    }

    public static void Remove(string key)
    {
        lock (_lock)
        {
            _cache.Remove(key);
            _keysList.Remove(key);
        }
    }

    public static void RemoveAll()
    {
        string[] keyArray = new string[_keysList.Count];
        _keysList.CopyTo(keyArray);
        foreach (string key in keyArray) { lock (_lock) { _cache.Remove(key); } }
        lock (_lock) { _keysList.Clear(); }
        keyArray.ExClear();
    }

    public static void Update<T>(string key, Func<T> getValue)
    {
        CacheItemPolicy policy = new CacheItemPolicy
        {
            AbsoluteExpiration = ObjectCache.InfiniteAbsoluteExpiration,
            SlidingExpiration = new TimeSpan(2, 0, 0),
            RemovedCallback =
                (arg) => { lock (_lock) { _keysList.Remove(arg.CacheItem.Key); } },
            Priority = CacheItemPriority.Default
        };

        Remove(key);

        lock (_lock) { _cache.Add(key, getValue(), policy); _keysList.Add(key); }
    }

    #endregion Public Methods
}

你这是什么意思?我已经使用WaitOne而不仅仅是键锁定了整个代码。锁定必须在对象级别,或者在静态中使用用于静态方法的静态全局对象,您使用的是内部局部变量而不是静态外部方法变量。这是不正确的。互斥体需要一个对象,我通过字符串的方式进行锁定,所以锁是按照每个用户建立的。像MyObjSuperman1,MyObjSuperman2等等。
public static class WebCache
{
    #region Private Fields

    private static readonly MemoryCache _cache = MemoryCache.Default;

    private static readonly HashSet<string> _keysList = new HashSet<string>();

    private static readonly object _lock = new object();

    #endregion Private Fields

    #region Public Methods

    public static T GetUpdate<T>(string key, Func<T> getValue)
    {
        if (_cache[key] == null) { Update(key, getValue); }

        return (T)_cache[key];
    }

    public static void Remove(string key)
    {
        lock (_lock)
        {
            _cache.Remove(key);
            _keysList.Remove(key);
        }
    }

    public static void RemoveAll()
    {
        string[] keyArray = new string[_keysList.Count];
        _keysList.CopyTo(keyArray);
        foreach (string key in keyArray) { lock (_lock) { _cache.Remove(key); } }
        lock (_lock) { _keysList.Clear(); }
        keyArray.ExClear();
    }

    public static void Update<T>(string key, Func<T> getValue)
    {
        CacheItemPolicy policy = new CacheItemPolicy
        {
            AbsoluteExpiration = ObjectCache.InfiniteAbsoluteExpiration,
            SlidingExpiration = new TimeSpan(2, 0, 0),
            RemovedCallback =
                (arg) => { lock (_lock) { _keysList.Remove(arg.CacheItem.Key); } },
            Priority = CacheItemPriority.Default
        };

        Remove(key);

        lock (_lock) { _cache.Add(key, getValue(), policy); _keysList.Add(key); }
    }

    #endregion Public Methods
}
object myCachedObj = WebCache.GetUpdate("KeyName", () => GetRequiredObject());