解决方案 »

  1.   

     Application.DoEvent()  ?
      

  2.   

    用线程,把接收到的数据放到list中,不作处理,后台开一个线程对list中的数据循环做处理,处理完了通知UI更新界面
      

  3.   

    谢谢您的回答,雷达的数据,一旦我程序执行读取数据以后,数据是不会段的,也就是说我模拟的代码中的i可能是无限大的,
    您这个处理完的依据是什么呢?50ms收一次数据全部都放在list?能给个事例说明么?
      

  4.   


    不太明白您的意思 
    但是雷达是持续扫描的,数据是实时刷新的。显示在datagridview上,数据会不停的变化着。这样线程就卡死了。不知道我这种情况代码该如何处理
      

  5.   

    你把每50ms一次的数据,全部显示在datagridview上,你以为datagridview是数据库吗
    不谈窗体假死时数据断不断的问题
    你跑24小时再看,保证卡死了
      

  6.   

    而且这么大的数据量,你不想办法存文件或数据库,而是放到控件里显示
    不管你是前台控件还是后台List
    你就不怕某一天内存爆掉了吗
      

  7.   

    这种数据,实时全部显示,根本毫无意义
    应该后台线程保持不断读数据,读到就放到List里
    然后另一个线程对List长度做判断,超过一定长度,入库或存文件,然后remove掉多余的数据
    前台控件定时(可以是1秒更新一次,不要太快)从List里把数据拿出来显示在控件上
      

  8.   

    我现在有个项目也是要刷新datagridview的,我用的办法是用一个线程接收信息,然后收到信息后,把信息存到队列中,然后隔几秒读取队列,显示到datagridview中
      

  9.   

    和之前@Z65443344说的类似,
    这个需求,在实现时需要注意两个点:一是程序的运行时间可能比较久,那就不要把数据都放到内存里。二是界面的刷新没必要和和数据的刷新同步,50ms一次更新,界面本来也反应不过来。你需要一个中间介质保存数据,我建议最好是一个数据库,如果是没有服务器的,可以使用像SQLite或者SQL Server Compact这样的嵌入式数据库。比起自己写文件来,一个好处是帮你实现了线程安全的读写,另一个是方便查询。然后需要两个缓冲区(可以就是list,最好创建时就固定好大小),开一个线程不断从设备读取数据到缓冲区,在数据到达一定量(这个可以根据系统性能调整)时,切换到另一个缓冲区,同时使用异步方法或另一个线程将之前填满的缓冲区一次性写入数据库。(其实SQLite每秒写20条数据很轻松,可能都不需要缓冲区)界面上用一个定时器比如1s从缓冲区或者数据库取数据显示到界面,不要一次加载所有数据,可以按需加载,比如默认加载最新的1000条。需要看之前的数据时再加载之前的。
      

  10.   

    50ms的刷新频率,显示出来的数据人眼根本就看不到,建立lz把这个业务分析清楚,最好能辨别出用人有用的数据转换成有用的信息,再显示出来。
      

  11.   

    雷达是50MS收一次数据,按照你们所说,如果我抛开这个50MS 那么是直接在内存处理好 还是先入库数据库?
    需求跟技术上实现基本都是我要考虑的  因为现在有一款老外写的软件,我看他的数据是实时刷新 也没有安装什么数据库之类的
      

  12.   

    关键点是50ms,50ms真心没必要,ui的刷新对系统的消耗挺大,1s 3s 甚至5s 其实对用户体验并没有多大区别。 至于数据,读取之后还是最好存储起来。 
      

  13.   

    可以看下我写的这个原型有没有帮助:https://code.csdn.net/snippets/495283
    这就是在一个线程模拟每50ms生成一条数据,然后UI上每200ms更新grid的代码。这个没考虑更多,只是看看和想要的"实时刷新"有什么距离。
      

  14.   


    _timer = new System.Windows.Forms.Timer(components) { Interval = 200 };
    谢谢你的回答,这个地方的components参数报错了 你测试过代码了么?
      

  15.   

    50ms异步刷新gridview速度上应该是够的。50ms刷新一次,也就是每秒20帧。创建合适的数据对象,绑定到gridview的datasource上。接收新数据后,更新数据源对象。更新后局部刷新变化了的数据。如果还觉得卡,可以调试和创建测试查看这个过程耗时的代码在哪里,进行优化,如果是ui反应不过来,那只好降低帧率,比如接收次数单次的数据不处理,只处理双次的,这样可以做到每秒10帧,gdi+应该可以处理过来了。最后:用gridview显示变化的数据不觉得很愚昧么?谁会盯着一个表格看上面的数字跳来跳去?
      

  16.   


    _timer = new System.Windows.Forms.Timer(components) { Interval = 200 };
    谢谢你的回答,这个地方的components参数报错了 你测试过代码了么?我当然测试过,WinForm的designer有时不生成这个components,去掉就是。
      

  17.   


    _timer = new System.Windows.Forms.Timer(components) { Interval = 200 };
    谢谢你的回答,这个地方的components参数报错了 你测试过代码了么?我当然测试过,WinForm的designer有时不生成这个components,去掉就是。明白了 感谢 ,还有最后一个问题,就是我现在的雷达最大的目标扫描数量是9个.
    也就是说,ID只能是0-9.然后每一个ID的后面的字段是实时变化的,比如开始1,然后按照你的程序200MS这个值可以直观的看到改变了。9个目标都是这样 ID不变。
      

  18.   

    50ms刷新一次界面,就算不卡,但频率过高肉眼也看不清楚啊,先将数据保存到内存中的List,1秒后再刷新界面并将数据写入到硬盘数据库或文件中,清空List再保存下一批,建议用后台线程处理数据吧
      

  19.   

    没看出来问题是什么我的意思是  实际上 雷达扫描的数据一共有9个目标 也就是有9个ID 但是每个目标的其他字段数据是在不断改变的,
    能麻烦你改造一下你得例子么。9个ID不变 其余的字段数据200MS改变刷新一次。我还在消化你的代码
      

  20.   

    我不了解具体需求,也不知道数据结构和界面具体是什么样子的,也帮不了更多了。那个原型代码估计也就是用了个ConcurrentQueue有些陌生。因为需要一个线程安全的结构来在两个线程之间传递数据,这些Concurrent开头的结构能够保证并发读写的线程安全,这个结构的功能也可以被一个数据库替换。可以把它想象成一个数据池,一方不断往里面填数据,另一方不断从里面取数据。然后就是UI控件不能直接绑定到这个结构上,需要隔离开才能保证UI不会对数据的生产方发生影响。所以把数据池里面的数据放到了一个专门做绑定用的BindingList里,它可以通过自己的变化直接触发UI更新,方便一点。这个后面还需要处理内存增长的问题,和界面能一次加载多少数据的问题。