C#实时接入数据进行更新 有个项目,需要处理实时数据,一个函数接入数据,20s读一次,读入数组,另一个函数从数组取出数据,执行,然后将结果导入数据库。接入数据会有延迟,我想用一个线程读数据,一个线程处理数据,或者有什么建议? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 可以啊两个线程,用ConcurrentQueue集合,一个压一个取 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 的任务,并等待消费者完成退出。 } }} 异步处理流程不外乎就是这样public void 处理(){ var data = 第一个函数(); ThreadPool.QueueUserWorkItem(h => 第二个函数(data));} 或者如果你不喜欢 ThreadPool.QueueUserWorkItem 方法那么就按照最近2年的语法来设计 async/await 异步方法。总之,这根本不纠结什么“两个线程”的说法。如果要定时20秒执行一次接入方法,那么就定时执行“处理”方法就行了,也是直截了当的。所谓动不动就说“我用几个线程”那其实反而是空谈,真正懂得异步多线程设计的人知道线程数量是动态的,根本不去纠结“2个”,可能是1个也可能是3个、5个,随算法设计和运行时的数据而变。 winform 新浪微博API获取自已的关注列表 access_token无法获取 运算符重载什么意思啊,为什么要运算符重载? C# datagridview 操作多级节点的xml文件问题 动态添加控件后出现的类型转换(请教) 结构中数组无法封装的问题 怎么在c#中检测sql2008数据库已经安装 菜鸟请教高手,关于字节数组的操作问题,在线等,急!!!! datagridview RowPostPaint 事件 C# 打开关闭EXE文件 calendar控件弹出 c## 求证一个关于ExecuteReader方法的问题,求解答
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 的任务,并等待消费者完成退出。
}
}
}
异步处理流程不外乎就是这样public void 处理()
{
var data = 第一个函数();
ThreadPool.QueueUserWorkItem(h => 第二个函数(data));
}