并发字典AddOrUpdate无法正确添加,更新和返回

时间:2015-11-10 13:11:04

标签: c# dictionary concurrentdictionary

我在C#中使用并发字典addOrUpdate。问题是这个字典不是主要的整个字典(列表)而不是它只将addOrUpdate最后一条记录放入字典中,并且该字典在字典中多次发现;我在foreach循环中遍历它。

//Volunteer Class
public class VolunteerMessage
{
    #region Variables
    public int UserId;
    public string UserName;
    public double Longitude;
    public double Latitude;
    public string Message;
    public string LocationTime;
    #endregion

    #region Public Methods
    public VolunteerMessage(string longit, string latit, string msg)
    {
        Message = msg;
        try
        {
            Longitude = Convert.ToDouble(longit);
            Latitude = Convert.ToDouble(latit);
        }
        catch (Exception exception)
        {
            Console.WriteLine(exception.Message);
        }
    }
    #endregion
}

private readonly ConcurrentDictionary<int, VolunteerMessage> _volunteerdict;
_volunteerdict = new ConcurrentDictionary<int, VolunteerMessage>();
var vappProDataObj = new VolunteerMessage(null, null, null);

try
{
    for (var i = 0; i < dsVolunteers.Tables[0].Rows.Count; i++)
    {
        vappProDataObj.UserId = Convert.ToInt32(dsVolunteers.Tables[0].Rows[i]["UserID"]);
        vappProDataObj.UserName = dsVolunteers.Tables[0].Rows[i]["UserName"].ToString();
        vappProDataObj.Longitude = Convert.ToDouble(dsVolunteers.Tables[0].Rows[i]["Latitude"].ToString());
        vappProDataObj.Latitude = Convert.ToDouble(dsVolunteers.Tables[0].Rows[i]["Longitude"].ToString());
        vappProDataObj.LocationTime = dsVolunteers.Tables[0].Rows[i]["LocationTime"].ToString();
        _volunteerdict.AddOrUpdate(vappProDataObj.UserId, vappProDataObj, (k, v) => vappProDataObj);

        Console.WriteLine(" Location Updaetd for " + vappProDataObj.UserName);
    }
    LogManager.Instance.WriteMessage("Volunteers List refreshed", "RefreshVolunteersList", null);
}
catch (Exception e)
{
    LogManager.Instance.WriteMessage("Volunteers List refreshing failed", "RefreshVolunteersList", e);
}

并且循环在这里:

VolunteerMessage itemFound = null;
double distance = 0;
foreach (var item in _volunteerdict)
{
    distance = GetDistanceFromLatLonInKm(Convert.ToDouble(e.Latit), Convert.ToDouble(e.Longit), Convert.ToDouble(item.Value.Latitude), Convert.ToDouble(item.Value.Longitude));

    if (distance <= 1000)
    {
        itemFound = item.Value;

        if (!itemFound.Equals(null))
        {
            Console.WriteLine(itemFound.UserName + " Is at " + distance + " from Location");
            _xmppConn.SendPrivateMessageXmpp(itemFound.UserName, e.Mesag);
        }
        else
            Console.WriteLine("No User found near message area");
    }
}

请告诉我我做错了什么?

提前致谢

2 个答案:

答案 0 :(得分:3)

您只创建vappPropDataObj的一个实例,并且正在编辑其值,而不是创建此对象的许多实例,每个实例都有自己的唯一值。因此,您的词典有许多键,所有键都指向同一个vappPropDataObj对象。

尝试写下这样的内容:

private readonly ConcurrentDictionary<int, VolunteerMessage> _volunteerdict;

try
{
    for (var i = 0; i < dsVolunteers.Tables[0].Rows.Count; i++)
    {
        var vappProDataObj = new VolunteerMessage(null, null, null);

        vappProDataObj.UserId = Convert.ToInt32(dsVolunteers.Tables[0].Rows[i]["UserID"]);
        vappProDataObj.UserName = dsVolunteers.Tables[0].Rows[i]["UserName"].ToString();
        vappProDataObj.Longitude = Convert.ToDouble(dsVolunteers.Tables[0].Rows[i]["Latitude"].ToString());
        vappProDataObj.Latitude = Convert.ToDouble(dsVolunteers.Tables[0].Rows[i]["Longitude"].ToString());
        vappProDataObj.LocationTime = dsVolunteers.Tables[0].Rows[i]["LocationTime"].ToString();
        _volunteerdict.AddOrUpdate(vappProDataObj.UserId, vappProDataObj, (k, v) => vappProDataObj);

        Console.WriteLine(" Location Updaetd for " + vappProDataObj.UserName);
    }
    LogManager.Instance.WriteMessage("Volunteers List refreshed", "RefreshVolunteersList", null);
}
catch (Exception e)
{
    LogManager.Instance.WriteMessage("Volunteers List refreshing failed", "RefreshVolunteersList", e);
}

答案 1 :(得分:1)

您正在对单个VolunteerMessage进行更新,并希望它在进入字典时成为许多对象。

您需要在循环中创建一个新的VoluteerMessage 来制作邮件的多个副本,否则您词典中的所有条目都会指向相同的单个邮件它的属性已经多次改变了。