Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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# 使用StackExchange.Redis的线程安全增量/减量_C#_Multithreading_Redis_Stackexchange.redis - Fatal编程技术网

C# 使用StackExchange.Redis的线程安全增量/减量

C# 使用StackExchange.Redis的线程安全增量/减量,c#,multithreading,redis,stackexchange.redis,C#,Multithreading,Redis,Stackexchange.redis,我使用StackExchange.Redis包作为多线程应用程序的共享存储,该应用程序将同时在多台服务器上运行……因此多线程;) 我拥有的一个最简单的用例是,我希望对一系列键(即KEY1=4、KEY2=7、KEY3=13等)进行基本计数。我将制定业务规则,以强制执行给定密钥允许的最大值。例如,假设KEY1只能高达5…如果两个线程同时启动并试图增加它,我只想让其中一个成功 我相信我可以通过一个事务来实现这一点,首先获取当前值,然后在该值未更改的条件下进行处理。这会像我期望的那样工作吗?有没有更优雅

我使用StackExchange.Redis包作为多线程应用程序的共享存储,该应用程序将同时在多台服务器上运行……因此多线程;)

我拥有的一个最简单的用例是,我希望对一系列键(即KEY1=4、KEY2=7、KEY3=13等)进行基本计数。我将制定业务规则,以强制执行给定密钥允许的最大值。例如,假设KEY1只能高达5…如果两个线程同时启动并试图增加它,我只想让其中一个成功

我相信我可以通过一个事务来实现这一点,首先获取当前值,然后在该值未更改的条件下进行处理。这会像我期望的那样工作吗?有没有更优雅的方法

    public void Increment(string key) {        
        IDatabase db = redisConn.GetDatabase();
        var val = db.StringGet(key);
        int maxVal = 5; 
        if (Convert.ToInt32(val) < maxVal) {
            var trans = db.CreateTransaction();
            trans.AddCondition(Condition.StringEqual(key, val));
            trans.StringIncrementAsync(key);
            trans.Execute();
        }
    }
公共无效增量(字符串键){
IDatabase db=redisConn.GetDatabase();
var val=db.StringGet(键);
int maxVal=5;
if(转换为32(val)

PS:我喜欢这个软件包,和它一起工作很愉快是的,应该很好用。但是通过
ScriptEvaluate
使用Lua脚本可能更容易、更高效


注意:对于当前代码,您可能需要检查
Execute
的响应,如果
false
,则检查“从头开始重做”。如果在从2移动到3时发生线程竞争,则使用当前代码:更新将被丢弃。这对Lua脚本来说不是问题。

谢谢你的回复,Marc,我不熟悉Lua脚本的用法,但今晚我会仔细阅读。简而言之,是什么让它更有效呢?@Bruceruser不需要中断多路复用器来确认断言,也不可能因为数据更改而失败;脚本类似于
如果tonumber(redis.call('get',KEYS[1])<5,那么redis.call('incr',KEYS[1])end
好的,我想我的脚本是正确的,但可能效率不高,下面是我为Increment编写的:string script=string.Format(“local val=tonumber(redis.call('get','0}'))或0如果val<{1}然后调用('INCR','{0}')end',key,maxValue);但奇怪的是,当我对它进行基准测试时,它的执行速度比使用事务慢……我的测试用例是100个唯一键上的100k递增和100k递减。使用事务处理,它以大约56秒的速度出现,而使用Lua脚本则是59秒。不过,这都是在一个线程上完成的,也许Lua赢了很多线程?