本文介绍了一个Concurrentdictionary中的更新反映在主字典中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

I have two concurrent dictionaries say

 ConcurrentDictionary<string, string> MainDic = new ConcurrentDictionary<string, string>();
and

ConcurrentDictionary<string, string> TempDic = new ConcurrentDictionary<string, string>(MainDic);

My TempDic contains same data as MainDic.I do computations on TempDic. whatever changes are made to TempDic is reflected in MainDic. How do i stop this ,i need to keep MainDic as it is for further reference





这里是我的代码:



here is my code:

ConcurrentDictionary<string, DataNetPosition> MainDic = new ConcurrentDictionary<string, DataNetPosition>();
private void GetNetPositionData()
{
    ConcurrentDictionary<string, DataNetPosition> Position;
    if (NetPosFlag == "A")
    {
        foreach (KeyValuePair<string, DataNetPosition> entry in MainDic)
        {
            this.DS.Tables[0].Rows.Add(entry.Value.A, entry.Value.B, entry.Value.C, entry.Value.D);
        }
    }
    else
    {
        Position = new ConcurrentDictionary<string, DataNetPosition>(GetDayPosition(MainDic));
        foreach (KeyValuePair<string, DataNetPosition> entry in Position)
        {
            this.DS.Tables[0].Rows.Add(entry.Value.A, entry.Value.B, entry.Value.C, entry.Value.D);
        }
    }

}

private ConcurrentDictionary<string, DataNetPosition> GetDayPosition(ConcurrentDictionary<string, DataNetPosition> _ALLPos)
{
    var TempDic = new ConcurrentDictionary<string, DataNetPosition>(_ALLPos);
    try
    {
        DataView dv = new DataView(DataSet1.Tables[0]);
        for (int i = 0; i < dv.Table.Rows.Count; i++)
        {
            string NKey = dv.Table.Rows[i][0].ToString() + dv.Table.Rows[i][1].ToString();
            if (TempDic.ContainsKey(NKey))
            {
                var dnp = TempDic[NKey];
                if (dv.Table.Rows[i][2].ToString() == "Buy")
                {
                    dnp.A = dnp.A - Convert.ToDouble(dv.Table.Rows[i]["Qty"]);
                    dnp.B = dnp.B - Convert.ToDouble(dv.Table.Rows[i]["TrdVal"]);
                }
                else
                {
                    dnp.C = dnp.C - Convert.ToDouble(dv.Table.Rows[i]["Qty"]);
                    dnp.D = dnp.D - Convert.ToDouble(dv.Table.Rows[i]["TrdVal"]);
                }
                dnp.E = dnp.E == 0 ? 0 : dnp.B / dnp.A;
                dnp.F = dnp.F == 0 ? 0 : dnp.D / dnp.C;
                dnp.G = dnp.A - dnp.C;
                // other caluculations
                TempDic.TryUpdate(NKey, dnp, null);
            }
        }
    }
    catch (Exception ex)
    {

    }
    return TempDic;
}





如果我的旗帜是A我使用MainDic,因为它是我打电话给



If my flag is A i use MainDic as it is else i call

GetDayPosition

的功能。在

GetDayPosition

函数中,我在TempDic中所做的任何更改都会反映在MainDic中,因此我的原始数据会丢失。我想保留我的数据MainDic。

function whatever changes i do in TempDic is reflected in MainDic as a result my original data is lost. i want to retain my data MainDic.

推荐答案

private ConcurrentDictionary<string,> dct1 = new ConcurrentDictionary<string,>();
private ConcurrentDictionary<string,> dct2;

private void TestConcurrent()
{
    dct1.TryAdd("1", "1");
    dct1.TryAdd("2", "2");
    dct1.TryAdd("3", "3");
    dct1.TryAdd("4", "4");
    
    dct2 = new ConcurrentDictionary<string,>(dct1);
    
    dct2["4"] = "5";
    
    dct1["3"] = "6";
}

如果在方法结束时设置断点,并检查两个ConcurrentDictionaries的内部值,您将看到它们之间没有耦合。 />


我会假设,你的'MainDic中的任何变化都不是'TempDic变化的结果,并且两者之间的任何明显同步都是由于你的复制造成的在你的一个线程操作中反复'TempDic into'MainDic。



我希望这种行为是因为,虽然字符串引用类型,它们通常通过值传递。有关此问题的详细讨论,请参阅Jon Skeet的分析[ ]:



Jon Skeet写道:

If you set a break-point at the end of the method, and examine the internal values of both ConcurrentDictionaries, you will see that there is no "coupling" between them.

I would hypothesize, then, that any changes in your 'MainDic are not a result of changes in 'TempDic, and that any apparent synchronization between the two is resulting from your copying 'TempDic into 'MainDic repeatedly in one of your threading operations.

I would expect this behavior because, while strings are a reference Type, they are normally passed by value. For a good discussion of this, see Jon Skeet's analysis [^]:

Jon Skeet wrote:


bool MainAdd;

           ConcurrentDictionary<string, string> MainDic = new ConcurrentDictionary<string, string>();
           MainDic.TryAdd("0", "Test");

           ConcurrentDictionary<string, string> TempDic =new ConcurrentDictionary<string, string> (MainDic);
           TempDic.TryAdd("1", "Test");

           txtMessage.Text += "\n TempDic Count : " + TempDic.Count.ToString();
           txtMessage.Text += "\n MainDic Count : " + MainDic.Count.ToString();

           MainAdd = MainDic.TryAdd("1", "Test");
           if (!MainAdd)
           {
               txtMessage.Text += "\n Not able to add Duplicate";
               txtMessage.Text += "\n TempDic Count : " + TempDic.Count.ToString();
               txtMessage.Text += "\n MainDic Count : " + MainDic.Count.ToString();
           }
           else
           {
               txtMessage.Text += "\n Added value successfully!";
               txtMessage.Text += "\n TempDic Count : " + TempDic.Count.ToString();
               txtMessage.Text += "\n MainDic Count : " + MainDic.Count.ToString();
           }





不确定你是否想做这样的事情......让我知道。



Not sure if you wanted to do something like this... let me know.



这篇关于一个Concurrentdictionary中的更新反映在主字典中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-21 23:53