有个项目,需要处理实时数据,一个函数接入数据,20s读一次,读入数组,另一个函数从数组取出数据,执行,然后将结果导入数据库。接入数据会有延迟,我想用一个线程读数据,一个线程处理数据,或者有什么建议?

解决方案 »

  1.   

    可以啊两个线程,用ConcurrentQueue集合,一个压一个取
      

  2.   

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Threading;
    ///生产者-消费者模式:
    ///1、一个存放任务的队列;
    ///2、当有任务需要执行的时候,将它放入到队列中,所以需要一个将任务放入队列的方法;
    ///3、生产者只需要生产,即只负责添加任务,所以添加完任务后,生产者线程是可以不用等待消费者执行完毕的(可以不阻塞);
    ///4、消费者线程从队列中获取任务(获取的同时移除,因此需要锁)并执行,所以需要while循环监听队列;
    ///5、在这个例子中,使用AutoResetEvent的优势在于没有任务的时候不会消耗CPU,在有任务的时候会立即响应
    namespace LLL
    {
        class ProducerConsumerQueue : IDisposable
        {
            EventWaitHandle _wh = new AutoResetEvent(false);
            Thread _worker;
            readonly object _locker = new object();
            Queue<string> _tasks = new Queue<string>();        public ProducerConsumerQueue()
            {
                _worker = new Thread(Work);
                _worker.Start();
            }        public void EnqueueTask(string task)
            {
                lock (_locker) _tasks.Enqueue(task);
                _wh.Set();
            }        public void Dispose()
            {
                EnqueueTask(null);     // 通知消费者退出
                _worker.Join();         // 等待消费者线程完成执行
                _wh.Close();            // 释放所有系统资源
            }        void Work()
            {
                while (true)
                {
                    string task = null;
                    //由于这里使用了锁,所以即便是启用多个消费者线程也不会出错
                    lock (_locker)
                        if (_tasks.Count > 0)
                        {
                            task = _tasks.Dequeue();
                            if (task == null) return;
                        }
                    if (task != null)
                    {
                        Console.WriteLine("Performing task: " + task);
                        Thread.Sleep(1000);  // 模拟执行工作...
                    }
                    else
                        _wh.WaitOne();         // 没有任务了,等待信号
                }
            }
        }
    }调用:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;namespace LLL
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (ProducerConsumerQueue q = new ProducerConsumerQueue())
                {
                    q.EnqueueTask("Hello");
                    for (int i = 0; i < 10; i++)
                    {
                        q.EnqueueTask("Say " + i);
                    }
                    q.EnqueueTask("Goodbye!");
                }            // 使用 using 语句结束时会调用 q 的 Dispose 方法
                // 该方法向队列中插入一个 null 的任务,并等待消费者完成退出。
            }
        }
    }
      

  3.   


    异步处理流程不外乎就是这样public void 处理()
    {
        var data = 第一个函数();
        ThreadPool.QueueUserWorkItem(h => 第二个函数(data));
    }
      

  4.   

    或者如果你不喜欢 ThreadPool.QueueUserWorkItem 方法那么就按照最近2年的语法来设计 async/await 异步方法。总之,这根本不纠结什么“两个线程”的说法。如果要定时20秒执行一次接入方法,那么就定时执行“处理”方法就行了,也是直截了当的。所谓动不动就说“我用几个线程”那其实反而是空谈,真正懂得异步多线程设计的人知道线程数量是动态的,根本不去纠结“2个”,可能是1个也可能是3个、5个,随算法设计和运行时的数据而变。