用于保存用户消息的静态字典

时间:2012-10-21 03:37:13

标签: c# asp.net-mvc dictionary static queue

我创建了一个静态类来保存用户消息,例如“项目已成功添加”或“密码已成功更改”等。在类中是一个包含所有消息的静态字典。字典的关键是UserId。然后我有一个在_Layout.cshtml中呈现的Action,这样即使它们被重定向到页面外,消息也会跟随用户。

例如,我可能允许用户“添加”项目,然后成功添加项目后,它将重定向到该项目的“列表”页面,然后显示消息“项目已成功添加”。

这很有效,直到我部署到我的生产网站,我发现消息“滞后”。我会添加一个项目,然后它将重定向到列表页面,但不会显示该消息。然后我会导航到应用程序中的其他位置,然后消息将显示在该页面上。

为什么会发生这种情况的任何想法?

这是我的UserMessageManager的代码

public static class UserMessageManager
{
    private static readonly Dictionary<int, Queue<UserMessage>> UserMessages = new Dictionary<int, Queue<UserMessage>>();

    public static void Add(int userId, string message)
    {
        if (string.IsNullOrWhiteSpace(message))
            return;

        if (!UserMessages.Keys.Contains(userId))
        {
            UserMessages.Add(userId, new Queue<UserMessage>());
        }

        UserMessages[userId].Enqueue(new UserMessage { Message = message});
    }

    public static List<UserMessage> Get(int userId)
    {
        if (!UserMessages.Keys.Contains(userId))
        {
            UserMessages.Add(userId, new Queue<UserMessage>());
        }

        var messages = new List<UserMessage>();
        while (UserMessages[userId].Any())
        {
            messages.Add(UserMessages[userId].Dequeue());
        }

        return messages;
    }
}

public class UserMessage
{
    public string Message { get; set; }
}
编辑:经过一些游戏,消息有时甚至会“束缚”。创建一些“项目”后,我会在字典中添加一条消息,并且这些消息会在看似随机的时间突然全部显示出来。

1 个答案:

答案 0 :(得分:5)

首先,如果这是一个真实的网站,我不会采取这种方法。如果您希望持久保存信息,请使用持久性内容(例如数据库)。否则,当AppDomain被回收或整个服务器出现故障时(你确实有冗余,对吗?),你将失去所有的消息。这种方法也不能很好地平衡负载。

其次,只是可能你看到标准集合类的结果不是线程安全的。没有任何同步或其他内存障碍,可能一个线程没有看到另一个线程写入的数据。两个线程完全可以同时写入字典(或写入同一列表)。您可以只添加一些同步,例如有一个锁定对象并锁定它为每个方法的整体。我开始使用数据库而不是......