C#上位机数据接收、数据存储及数据显示有关问题

C#上位机数据接收、数据存储及数据显示问题
我采用TCP/ip协议,通过上位机接收下位机传来的数据,在上位机完成数据存储和数据显示(波形)。数据量比较大,又要求显示的实时性,显示采用GDI画图的控件。流程如图。现有一问题,数据显示时,会导致网速变慢,即传输数据变少,时间久了会造成数据丢失。
问题是:通过什么方法能够即满足实时性,又能不会丢数据
C#上位机数据接收、数据存储及数据显示有关问题
------解决思路----------------------
1.为了保证数据接收的完整性,接收、存储和显示数据不要放在一个线程中。
2.数据显示可以采取一定的策略进行筛选或者跳过,刷新快于1秒,对于用户来说意义不大。


------解决思路----------------------
关键点就是异步/多线程、缓存/批量处理,数据接收、显示、数据保存显然不应该使用一个线程,显示肯定是 UI 线程,其它两个要不然用异步 I/O 方式,要不然使用独立的线程。

最简单的形式就是:接收数据的任务不断收下位机数据,放到缓存(一般是队列形式)里。一个线程从缓存中取数据,取得一定数量或者超时后,把取到的一组数据交给 UI 和保存任务,进行显示和保存。
------解决思路----------------------
从“开始”到“接收数据”之间的箭头,应该是一个“数据关联”的箭头,而不是一个控制箭头。“开始”操作应该只是注册系统底层去异步处理“接收数据”,注册完毕之后也就可以结束了。而系统底层在接收到数据之后,会自动启动“接收数据”处理方法。

从“接收数据”到“显示数据”之间的那个箭头,应该是一个“注册并发任务”的箭头,是异步的而不是同步的去显示数据的!当接收数据的处理过程注册给“系统线程池”一个显示数据的任务委托之后,接收数据操作就结束了。

“显示数据”部分,你可以设计某个“防止重入”标志变量。当发现前一个操作还没有结束(还没有设置这个标志为false)时,或者是“接收数据”操作根本不注册新的“显示数据”委托,或者是“显示数据”操作在一开始就直接结束(跳出)而不用去显示了。这样避免了重复并发调用或者同步排队调用“显示数据”操作。遇到并发的情况,直接丢掉“显示数据”任务就行了,而不需要排队。

在“显示数据”的实际处理时,应该总是从“上一次显示的数据的位置”开始显示。显示了数据则从List<> 中移除(由于不存在存在并发,因此其实不需要考虑 lock 互斥操作)。

“存储数据”其实不应该在“”显示数据“之后才执行。你把它安排在这里,说明你在开发设计中有些懒惰、图省事。

数据的保存的重要性,并不是决定于它有没有曾经显示完毕。因此在“接收数据”之后,它在注册给系统线程池一个“显示数据”操作之后,就应该立刻注册给系统线程池一个“存储数据”的任务委托。这里无需再把数据放到什么队列中(不需要像“显示数据”那样去考虑只有一个任务去操作),收到一块数据就注册一个任务去保存这块数据。如果你的存储的驱动本身支持并发多任务(例如通过ado.net向关系数据库写入多条记录,多线程可以分别inser自己的数据记录),也不需要考虑是否同时有其它的“存储过程”的线程同时操作的问题。
------解决思路----------------------
如果从代码的角度来说 正如@以专业开发人员为伍 说的.

因为你是实时性的 所以 一般也不需要"显示队列"


void 接收数据(byte[] data)
{
  var rs=数据转换对象(data);
  ThreadPool.QueueUserWorkItem(h => 存储(rs));
  ThreadPool.QueueUserWorkItem(h => 显示(rs));
}
void 存储(object rs)
{
  // insert into ....
}
void 显示(object rs)
{
 //这里面你是gdi+还是图形那是你的事了.....
}


不过 一般说"显示采用GDI画图的控件"都是装B的做法..控件一大把不用 非得自己画才能显示出自己的实例吗?

人家控件做的很牛逼了 几百万个点一下子就画上了  难道你写的会比人家的效率高?

当然了 如果你说的数据比较大  是一秒几E个..那我也无话可说了.
------解决思路----------------------
http://blog.****.net/leichelle/article/details/7994383

个人而言我觉得这个比较不错 我也在用 功能强大 能满足类似工业级别的要求..

并且实时性比较好 又有游标之类的工具 一般扔几十万或者几百万个动态点 也没什么问题...
------解决思路----------------------
我需要实现动态效果(波                             //形随时间向左平移),所以需要刷新的很快。
你完全可以每5秒发送一次数据(5秒的全部数据),然后显示的地方不要一股脑都显示,而是做个类似动画效果一样的,一个一个的显示出来.
而不是每要显示一个数据,都必须通信一次