gpt4 book ai didi

caching - 具有 Windows Server AppFabric 缓存的分布式锁服务

转载 作者:行者123 更新时间:2023-12-04 17:04:50 24 4
gpt4 key购买 nike

我在 Windows Server AppFabric SDK 中找到了 Microsoft.ApplicationServer.Caching.DataCache 对象的扩展方法,如下所示:

using System;
using System.Collections.Generic;
using Microsoft.ApplicationServer.Caching;

namespace Caching
{
public static class CacheExtensions
{
private static Dictionary<string, object> locks = new Dictionary<string, object>();

public static T Fetch<T>(this DataCache @this, string key, Func<T> func)
{
return @this.Fetch(key, func, TimeSpan.FromSeconds(30));
}

public static T Fetch<T>(this DataCache @this, string key, Func<T> func, TimeSpan timeout)
{
var result = @this.Get(key);

if (result == null)
{
lock (GetLock(key))
{
result = @this.Get(key);

if (result == null)
{
result = func();

if (result != null)
{
@this.Put(key, result, timeout);
}
}
}
}

return (T)result;
}

private static object GetLock(string key)
{
object @lock = null;

if (!locks.TryGetValue(key, out @lock))
{
lock (locks)
{
if (!locks.TryGetValue(key, out @lock))
{
@lock = new object();
locks.Add(key, @lock);
}
}
}

return @lock;
}
}
}

目的是让开发人员编写这样的代码:“首先尝试缓存来获取一些数据。如果缓存中不可用,则执行指定的函数,将结果放入缓存中供下一个调用者使用,然后返回结果”。像这样:
var data = dataCache.Fetch("key", () => SomeLongRunningOperation());

锁定将可能长时间运行的函数调用的执行限制为单个线程,但仅限于同一台机器上的单个进程。您将如何扩展这种模式以分散锁定以防止多个进程/机器同时执行该功能?

最佳答案

AppFabric 拥有自己的分布式锁定机制,您可以通过 GetAndLock/PutAndUnlock 访问该机制。方法族。如果您的元素被锁定,则是正常的 Get调用仍然会成功并返回最后一个值,但进一步GetAndLock调用将抛出异常。在您的客户端第一次请求缓存对象的情况下,您仍然可以锁定 key ,即使它实际上还不存在(它更像是一个保留而不是一个实体锁)。

public static T Fetch<T>(this DataCache @this, string key, Func<T> func, TimeSpan timeout)
{
var result = @this.Get(key);

if (result == null)
(
DataCacheLockHandle handle;
// We need a timespan to allow func time to run
TimeSpan funcTimespan = New TimeSpan(0,1,0);

try
{
// Lock the key
// If something goes wrong here it will unlock at the end of funcTimespan
var result = @this.GetAndLock(key, funcTimespan, handle);

if (result == null)
{
// Still no value so go and run func
result = func();

@this.PutAndUnlock(key, result, handle, timeout);
}
else
{
// There's a value now so we'll unlock the key and reset it's timeout
@this.Unlock(key, handle, timeout);
}
}
catch (DataCacheException ex)
{
if (ex.ErrorCode == DataCacheErrorCode.ObjectLocked)
{
// Another process has locked the key so func must be running right now
// We'll return null to the client
result = null;
}
}

if (result == null)
{
return null;
}
else
{
return (T)result;
}
)
}

关于caching - 具有 Windows Server AppFabric 缓存的分布式锁服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5094050/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com