简体   繁体   English

使用线程安全的ConcurrentDictionary集合

[英]Using thread-safe ConcurrentDictionary collection

I've a such function which uses unthread-safe collection List, also to be thread-safe it uses lock-operator: 我有一个这样的函数,它使用非线程安全的集合列表,也为了线程安全,它使用了锁操作符:

public void ShowData(ref DataGridView dmRequests, ref DataGridView URL, ref DataGridView dmData, ref DataGridView errorCodes)
{
    List<KeyValuePair<string, ulong>> dmReqList = new List<KeyValuePair<string, ulong>>();
    List<KeyValuePair<string, ulong>> urlReqList = new List<KeyValuePair<string, ulong>>(); 
    List<KeyValuePair<string, ulong>> dmDataList = new List<KeyValuePair<string, ulong>>();
    List<KeyValuePair<string, ulong>> errCodesList = new List<KeyValuePair<string, ulong>>();

    lock (m_logStruct.domainName)
    {
        dmReqList = m_logStruct.domainName.ToList();
    }
    lock(m_logStruct.URL)
    {
        urlReqList = m_logStruct.URL.ToList();
    }
    lock(m_logStruct.domainData)
    {
        dmDataList = m_logStruct.domainData.ToList();
    }
    lock(m_logStruct.errorCodes)
    {
        errCodesList = m_logStruct.errorCodes.ToList();
    }

    dmRequests.DataSource = dmReqList.OrderBy(x => x.Key).ToList();
    URL.DataSource = urlReqList.OrderBy(x => x.Key).ToList();
    dmData.DataSource = dmDataList.OrderBy(x => x.Key).ToList();
    errorCodes.DataSource = errCodesList.OrderBy(x => x.Key).ToList();
}

I want to convert it to do it lock-free. 我想将其转换为无锁。 To do it I've used in this function ConcurrentDictionary collection instead of List collection, so my function begin look so: 为此,我在此函数中使用ConcurrentDictionary集合而不是List集合,因此我的函数开始看起来像这样:

public void ShowData(ref DataGridView dmRequests, ref DataGridView URL, ref DataGridView dmData, ref DataGridView errorCodes)
{
    try
    {
        ConcurrentDictionary<string, ulong> dmReqList = new ConcurrentDictionary<string, ulong>();
        ConcurrentDictionary<string, ulong> urlReqList = new ConcurrentDictionary<string, ulong>();
        ConcurrentDictionary<string, ulong> dmDataList = new ConcurrentDictionary<string, ulong>();
        ConcurrentDictionary<string, ulong> errCodesList = new ConcurrentDictionary<string, ulong>();

        dmReqList = m_logStruct.domainName;
        urlReqList = m_logStruct.URL;
        dmDataList = m_logStruct.domainData;
        errCodesList = m_logStruct.errorCodes;

        dmRequests.DataSource = dmReqList.OrderBy(x => x.Key);
        URL.DataSource = urlReqList.OrderBy(x => x.Key).ToList();//I get error here: Index is out of range                
        dmData.DataSource = dmDataList.OrderBy(x => x.Key).ToList();              
        errorCodes.DataSource = errCodesList.OrderBy(x => x.Key).ToList();
    }
    catch(IOException e)
    {
        MessageBox.Show(e + " Something bad has been occurred here!");
    }

}

But in this function I begin get error(Index is out of range). 但是在此函数中,我开始出现错误(索引超出范围)。 How to use thread-safe collection(ConcurrentDictionary) correctly? 如何正确使用线程安全集合(ConcurrentDictionary)? How to fix my error? 如何解决我的错误?

It's not going to be concurrent if you're replacing the variable where you're storing the list. 如果要在存储列表的位置替换变量,则不会是并发的。 You need to use the concurrent methods that it provides. 您需要使用它提供的并发方法。 See the examples in the MSDN article . 请参阅MSDN文章中的示例。

Use TryAdd , TryUpdate , TryRemove or AddOrUpdate in order to add to the list or update the list so rather than: 使用TryAddTryUpdateTryRemoveAddOrUpdate以添加到列表或更新列表,这样,而不是:

dmReqList = m_logStruct.domainName;

Do something like: 做类似的事情:

foreach (var item in m_logStruct.domainName)
{
    dmReqList.TryAdd(item.Key, item.Value);
}

UPDATE: As pointed out by Alexei, you're defining the dmReqList locally. 更新:正如Alexei指出的那样,您正在本地定义dmReqList。 This means that you're getting no benefit from it being a ConcurrentDictionary because no other thread could access it anyway. 这意味着您不能从ConcurrentDictionary中受益,因为任何其他线程都无法访问它。 Also, you imply from your original example that m_logStruct is accessible via other threads because you applied the lock to it. 另外,您从原始示例中暗示m_logStruct可通过其他线程访问,因为您已对其施加了锁定。 If the implication is correct, then that is what needs to be a ConcurrentDictionary. 如果含义正确,那么这就是ConcurrentDictionary。 So, your code would need to look more like this: 因此,您的代码将需要看起来像这样:

private ConcurrentDictionary<string, ulong> _domainNames = new ConcurrentDictionary<string, ulong>();

public void ShowData(ref DataGridView dmRequests)
{
    dmRequests.DataSource = _domainNames.OrderBy(x => x.Key);  //Set the current values of the dictionary to the grid.
}

public void MultiThreadedMethod()
{
    _domainNames.TryAdd(someKey, someValue);  //Access the dictionary from multiple threads.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 对ConcurrentDictionary的线程安全更改 - Thread-safe changes to a ConcurrentDictionary 这是ConcurrentDictionary和ConcurrentQueue线程安全的组合吗? - Is this combination of ConcurrentDictionary and ConcurrentQueue thread-safe? 在 if 语句中使用 ConcurrentDictionary TryGetValue 是否会使 if 内容线程安全? - Does using ConcurrentDictionary TryGetValue within an if statement make the if contents thread-safe? ThreadStatic属性还是ConcurrentDictionary? 线程安全哪个更好? - ThreadStatic Attribute or ConcurrentDictionary? Which is better for thread-safe? ConcurrentDictionary 中项目的 C# 线程安全原子操作 - C# thread-safe atomic operation on item in ConcurrentDictionary 多级ConcurrentDictionary是否仍然是线程安全的? - Is multi-level ConcurrentDictionary still thread-safe? 在ConcurrentDictionary线程中按索引更新值的属性是否安全? - Is updating properties of value by index in ConcurrentDictionary thread-safe? .NET的ConcurrentDictionary的哪些成员是线程安全的? - Which members of .NET's ConcurrentDictionary are thread-safe? .NET4.0:ConcurrentDictionary的线程安全更新<TKey, TValue> - .NET4.0: Thread-Safe Updating of ConcurrentDictionary<TKey, TValue> 如何以线程安全的方式在.NET ConcurrentDictionary上调用GetOrAdd方法? - How to call the GetOrAdd method on a .NET ConcurrentDictionary in a thread-safe way?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM