2

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

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

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

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

这是我的 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; }
}

编辑:经过一番玩弄之后,消息有时甚至会“聚集”起来。创建一些“项目”后,我将在字典中添加一条消息,这些消息会突然在看似随机的时间同时显示。

4

1 回答 1

5

首先,如果这是针对真实站点的,我无论如何都不会采用这种方法。如果您希望信息持久化,请使用持久化的东西(例如数据库)。否则,当 AppDomain 被回收或整个服务器出现故障时(您确实有冗余,对吗?)您将丢失所有消息。这种方法也不能很好地进行负载平衡。

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

于 2012-10-21T06:26:19.200 回答