问题描述
问题描述:C#编写的应用,需要从采集设备读取大容量数据→然后进行数据处理限制如下:1、数据采集可能需要较长时间,数据处理也需要较长时间→因此如果等采集完毕才进行处理,处理完毕再进行采集,效率就不够高;为此,我拟采用双缓冲方式:即有两个采集缓冲区A/B,当A采集满后立即采用异步方式进行数据处理,并紧接着用缓冲区B进行数据采集,采集完毕同样采用异步方式进行数据处理;2、在“数据处理”时必须确保只有一个“数据处理”过程被启用。(如果用生产者/消费者来描述的话应该说任何时刻只能有1个消费者)我现在实现时出现的问题://缓冲区声明int[]bufferA,bufferB;//设缓冲区大小均为4096//同步变量AutoResetEventautoEvent1,autoEvent2;//初始化时参数为(true,即非终止状态)//等待句柄数组WaitHandle[]waitHandles={autoEvent1,autoEvent2};///////////////////数据采集线程函数/////////////////voidDataRequest(){while(true){intnIndex=WaitHandle.WaiAny(waitHandles);if(nIndex==0){//从设备采集数据到bufferA........................................................//发消息通知处理线程进行“数据处理”:采用Win32API函数PostMessage(HWND,MSG1,wParam,lParam)//这里没有采用SendMessage函数是我认为SendMessage是同步调用,这样在“数据处理”完成前就不能继续采集数据了}elseif(nIndex==1){//从设备采集数据到bufferB........................................................//发消息通知处理线程进行“数据处理”:采用Win32API函数PostMessage(HWND,MSG2,wParam,lParam)//这里没有采用SendMessage函数是我认为SendMessage是同步调用,这样在“数据处理”完成前就不能继续采集数据了}}}////////////////重写WinForm的WndProc消息处理函数//////////////protectedoverridevoidWndProc(MSGm){if(m.Msg==MSG1){BufferADataProcess();}elseif(m.Msg==MSG2){BufferBDataProcess();}}///////////////数据处理线程函数:处理A缓冲区数据/////////////voidBufferADataProcess(){//数据处理..................................//释放一个句柄,以便数据采集可以进行autoEvent1.Set();}///////////////数据处理线程函数:处理B缓冲区数据/////////////voidBufferBDataProcess(){//数据处理..................................//释放一个句柄,以便数据采集可以进行autoEvent2.Set();}///////////////////////////////////////////现在的问题///////////////////////////////////////////现在的问题///////////////////////////////////////////现在的问题1、由于数据采集线程采集数据较快,导致发送消息PostMessage比较快,这样导致有可能有多个“数据处理”过程被同时调用,这违反了上述规则2,导致系统无法工作!===================================================>如何解决该问题?即如何确保“数据处理”只有一个被PostMessage消息启动?
解决方案
解决方案二:
如果不用postmessage呢?是否可以把数据保存到hashtable或者dictionary里面,然后采集线程就不停的往这个里面加数据然后你的处理线程就不停的处理相关的数据,这样可能会到点吧?或者你发消息的时候给消息定义一个规则就是当某些消息存在(也就是你的处理线程还在使用中的情况)此时暂停发送消息,一直到你的线程处理好数据以后,发消息告诉你的程序,采集线程启动
解决方案三:
参考http://blog.csdn.net/ghj1976/archive/2000/12/17/3257.aspxhttp://blog.csdn.net/skyjacker/archive/2007/01/04/1473378.aspxhttp://blog.csdn.net/liuya1985liuya/archive/2006/10/29/1355131.aspx
解决方案四:
盼高手指点一二为谢!!!
解决方案五:
up
解决方案六:
在数据采集完成,准备发消息通知数据处理的时候,先检查另一个数据采集的同步变量。A数据采集完成,先检查B的同步变量。B数据采集完成,先检查A的同步变量。即,进入A数据处理的条件是,B数据处理完成。voidDataRequest(){while(true){intnIndex=WaitHandle.WaiAny(waitHandles);if(nIndex==0){//从设备采集数据到bufferA........................................................autoEvent2.WaiteOne();//发消息通知处理线程进行“数据处理”:采用Win32API函数PostMessage(HWND,MSG1,wParam,lParam)//这里没有采用SendMessage函数是我认为SendMessage是同步调用,这样在“数据处理”完成前就不能继续采集数据了}elseif(nIndex==1){//从设备采集数据到bufferB........................................................autoEvent1.WaiteOne();//发消息通知处理线程进行“数据处理”:采用Win32API函数PostMessage(HWND,MSG2,wParam,lParam)//这里没有采用SendMessage函数是我认为SendMessage是同步调用,这样在“数据处理”完成前就不能继续采集数据了}}}
解决方案七:
首次执行需要处理一下吧
解决方案八:
本来我以为通过PostMessage给主窗口的WndProc可以实现:WndProc函数会阻止多个Message到来时按顺序执行完一个才执行下一个Message,谁知WndProc好像会让多个Message都起来,从而在主线程中同时调用多个消息处理函数,导致结果不对!...............................是这样的吗???