You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ConcurrentQueue入队后无法出队:单例Repository哈希码不一致问题

问题分析与解决方案

问题根源

哈希码不一致直接说明:你在AddItem方法和循环处理逻辑中操作的是两个完全不同的ConcurrentQueue<Order>实例。本质原因是你的Repository单例模式实现错误,导致系统中存在多个Repository实例,每个实例都维护了自己独立的队列——接口调用的是A实例的队列,循环处理的是B实例的队列,自然拿不到数据。

排查与修复步骤

  1. 检查单例实现的核心错误点

    • 确认Repository的构造函数是否为private:如果构造函数是公共的,外部代码可以随意new出新的实例,直接破坏单例
    • 检查单例属性的getter逻辑:比如是否在get里错误地每次都返回new Repository(),或者懒加载的双重检查锁写错了,导致每次获取实例都创建新对象
    • 若使用了依赖注入(比如ServiceStack的IOC容器):确认是否把Repository注册为单例,而非每次请求都创建新实例
  2. 修复单例实现(示例)
    下面是一个标准的饿汉式单例实现,避免多线程下的实例重复创建问题:

    public class Repository
    {
        // 静态只读实例,类加载时初始化,保证唯一
        private static readonly Repository _instance = new Repository();
        // 队列实例与单例绑定,确保全局唯一
        private readonly ConcurrentQueue<Order> _orderQueue = new ConcurrentQueue<Order>();
    
        // 私有构造函数,禁止外部实例化
        private Repository() {}
    
        // 全局访问入口
        public static Repository Instance => _instance;
    
        public void AddItem(Order order)
        {
            _orderQueue.Enqueue(order);
            // 可添加日志验证:Console.WriteLine($"AddItem 队列哈希: {_orderQueue.GetHashCode()}");
        }
    
        public void CreateOrder()
        {
            while (true)
            {
                // 可添加日志验证:Console.WriteLine($"处理循环 队列哈希: {_orderQueue.GetHashCode()}");
                if (_orderQueue.TryDequeue(out var order))
                {
                    // 执行订单处理逻辑
                }
                // 空转时休眠,降低CPU占用
                Thread.Sleep(100);
            }
        }
    }
    
  3. 统一实例获取方式

    • Service类中必须通过Repository.Instance调用AddItem,禁止自行new Repository()
    • 应用启动时的线程,同样通过Repository.Instance调用CreateOrder方法
  4. 验证修复效果
    在AddItem和CreateOrder方法中分别输出队列的哈希码,确认两次输出的哈希码完全一致,说明操作的是同一个队列实例。

额外注意事项

  • 如果使用ServiceStack的依赖注入,需在容器中注册单例:
    container.RegisterAs<Repository, IRepository>(ReuseScope.Singleton);
    
    确保Service类通过构造函数注入的IRepository是全局唯一实例
  • 后台线程处理订单时,若需要更新UI,必须通过WinForms的Control.Invoke/Control.BeginInvoke切换到UI线程操作,避免跨线程异常

内容的提问来源于stack exchange,提问作者Saghar Francis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 14:01:13