gpt4 book ai didi

c# - 如何动态锁定字符串但从内存中删除锁定对象

转载 作者:行者123 更新时间:2023-12-03 12:55:21 27 4
gpt4 key购买 nike

我有以下情况:

我的项目中有很多线程,每个线程按时间处理一个“键”。

两个线程不能同时处理相同的“ key ”,但是我的项目处理的是“ key 的笨拙”,因此我无法将“ key ”存储在内存中,我需要在内存中存储线程正在处理“ key ” ”,如果另一个线程尝试处理相同的“键”,则该线程将在lock子句中等待。

现在,我具有以下结构:

   public class Lock
{
private static object _lockObj = new object();
private static List<object> _lockListValues = new List<object>();

public static void Execute(object value, Action action)
{
lock (_lockObj)
{
if (!_lockListValues.Contains(value))
_lockListValues.Add(value);
}

lock (_lockListValues.First(x => x.Equals(value)))
{
action.Invoke();
}
}
}

一切正常,问题在于没有从内存中删除 key 。最大的麻烦是多线程功能,因为可以随时处理“ key ”。

如果没有独立于 key 的全局锁,我该如何解决呢?

最佳答案

抱歉,但不是,这不是应该这样做的方法。

首先,您谈论 key ,但是将 key 作为类型对象存储在List中,然后使用LINQ进行搜索以从列表中获取 key 。

对于这种东西在这里字典。

其次,对象模型,通常最好是围绕某个类实现某些对象的锁定,使其美观大方:

喜欢:

using System.Collections.Concurrent;


public LockedObject<T>
{
public readonly T data;
public readonly int id;
private readonly object obj = new object();
LockedObject(int id, T data)
{
this.id = id;
this.data = data;

}

//Usually, if you have Action related to some data,
//it is better to receive
//that data as parameter

public void InvokeAction(Action<T> action)
{
lock(obj)
{
action(data);
}
}

}

//Now it is a concurrently safe object applying some action
//concurrently on given data, no matter how it is stored.
//But still, this is the best idea:


ConcurrentDictionary<int, LockedObject<T>> dict =
new ConcurrentDictionary<int, LockedObject<T>>();

//You can insert, read, remove all object's concurrently.

但是,最好的事情尚未到来! :)您可以轻松地将其锁定为自由状态!

编辑1:

ConcurrentInvoke,类似于集合的字典,用于同时安全地对数据进行调用。一次在给定的键上只能执行一项操作。
using System;
using System.Threading;
using System.Collections.Concurrent;


public class ConcurrentInvoke<TKey, TValue>
{
//we hate lock() :)

private class Data<TData>
{
public readonly TData data;
private int flag;
private Data(TData data)
{
this.data = data;
}
public static bool Contains<TTKey>(ConcurrentDictionary<TTKey, Data<TData>> dict, TTKey key)
{
return dict.ContainsKey(key);
}
public static bool TryAdd<TTKey>(ConcurrentDictionary<TTKey, Data<TData>> dict, TTKey key, TData data)
{
return dict.TryAdd(key, new Data<TData>(data));
}
// can not remove if,
// not exist,
// remove of the key already in progress,
// invoke action of the key inprogress
public static bool TryRemove<TTKey>(ConcurrentDictionary<TTKey, Data<TData>> dict, TTKey key, Action<TTKey, TData> action_removed = null)
{
Data<TData> data = null;
if (!dict.TryGetValue(key, out data)) return false;

var access = Interlocked.CompareExchange(ref data.flag, 1, 0) == 0;
if (!access) return false;

Data<TData> data2 = null;
var removed = dict.TryRemove(key, out data2);

Interlocked.Exchange(ref data.flag, 0);

if (removed && action_removed != null) action_removed(key, data2.data);
return removed;
}
// can not invoke if,
// not exist,
// remove of the key already in progress,
// invoke action of the key inprogress
public static bool TryInvokeAction<TTKey>(ConcurrentDictionary<TTKey, Data<TData>> dict, TTKey key, Action<TTKey, TData> invoke_action = null)
{
Data<TData> data = null;
if (invoke_action == null || !dict.TryGetValue(key, out data)) return false;

var access = Interlocked.CompareExchange(ref data.flag, 1, 0) == 0;
if (!access) return false;

invoke_action(key, data.data);

Interlocked.Exchange(ref data.flag, 0);
return true;
}
}

private
readonly
ConcurrentDictionary<TKey, Data<TValue>> dict =
new ConcurrentDictionary<TKey, Data<TValue>>()
;

public bool Contains(TKey key)
{
return Data<TValue>.Contains(dict, key);
}
public bool TryAdd(TKey key, TValue value)
{
return Data<TValue>.TryAdd(dict, key, value);
}
public bool TryRemove(TKey key, Action<TKey, TValue> removed = null)
{
return Data<TValue>.TryRemove(dict, key, removed);
}
public bool TryInvokeAction(TKey key, Action<TKey, TValue> invoke)
{
return Data<TValue>.TryInvokeAction(dict, key, invoke);
}
}




ConcurrentInvoke<int, string> concurrent_invoke = new ConcurrentInvoke<int, string>();

concurrent_invoke.TryAdd(1, "string 1");
concurrent_invoke.TryAdd(2, "string 2");
concurrent_invoke.TryAdd(3, "string 3");

concurrent_invoke.TryRemove(1);

concurrent_invoke.TryInvokeAction(3, (key, value) =>
{
Console.WriteLine("InvokingAction[key: {0}, vale: {1}", key, value);
});

关于c# - 如何动态锁定字符串但从内存中删除锁定对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33786579/

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