并发字典 AddOrUpdate 没有正确添加、更新和返回

Concurrent Dictionary AddOrUpdate not adding, updating and returning correctly

我在 C# 中使用并发字典 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");
    }
}

请告诉我我做错了什么?

提前致谢

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

您需要在循环中创建一个新的VoluteerMessage 来制作消息的多个副本,否则您字典中的所有条目都将指向同一条消息的属性已更改多次。

您只创建了一个 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);
}