各位大侠如何解决啊,,,,新手呜呜。。。。。。。
或者有更好的方法!!!!!
6 个解决方案
#1
详细说明你是怎么做的,别人才知道哪里出了问题。
我怀疑你其实用的是Timer而不是多线程。
我怀疑你其实用的是Timer而不是多线程。
#2
//主程序开始就启动线程
//线程部分(里面的循环,每次循环都在2000数据左右)
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "LEDDataBufferUnit.h"
#include "datamodule.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// Important: Methods and properties of objects in VCL can only be
// used in a method called using Synchronize, for example:
//
// Synchronize(UpdateCaption);
//
// where UpdateCaption could look like:
//
// void __fastcall LEDDataBuffer::UpdateCaption()
// {
// Form1->Caption = "Updated in a thread";
// }
//---------------------------------------------------------------------------
__fastcall LEDDataBuffer::LEDDataBuffer(bool CreateSuspended)
: TThread(CreateSuspended)
{
//Timer1->Interval=10000;
}
//---------------------------------------------------------------------------
/*
void __fastcall LEDDataBuffer::Timer1Timer(TObject *Sender)
{
//Synchronize(ExecSQL);
}
*/
void __fastcall LEDDataBuffer::ExecSQL()
{
sql="select L.BufferID,T.* from (select showno,count(showno)as [Count] from LEDDataBuffer \
group by showno having count(showno) >1)T join LEDSendData L on T.ShowNo=L.ShowNo";
DataModule1->show(sql,DataModule1->ADOQLEDDataBufferThirdShow);
//循环检索这个区域在缓存的数据
while(!DataModule1->ADOQLEDDataBufferThirdShow->Eof)
{
//检索1--检索按照ID排序大约正在播放ID的数据
sql="select top 1* from LEDDataBuffer where ShowNo="+DataModule1->ADOQLEDDataBufferThirdShow->FieldByName("ShowNo")->AsString+" \
and ID>"+DataModule1->ADOQLEDDataBufferThirdShow->FieldByName("Bufferid")->AsString;
DataModule1->show(sql,DataModule1->ADOQLEDDataBufferThirdShow1);
//检索1---无结果--表示已经是最后一个了,要返回到第一个数据
if(DataModule1->ADOQLEDDataBufferThirdShow1->Eof)
{
//检索2---检索这个区域在缓存的第一个数据
sql="select top 1* from LEDDataBuffer where ShowNo="+DataModule1->ADOQLEDDataBufferThirdShow->FieldByName("ShowNo")->AsString+"\
order by ID asc";
DataModule1->show(sql,DataModule1->ADOQLEDDataBufferThirdShow1);
if(DataModule1->ADOQLEDDataBufferThirdShow1->Eof)
{
//检索2---无结果--表示已经是已经没有数据,返回空!!
sql="select top 1 0 as ID ,'' as ShowNo,'' as SendData,'红色' as Color from LEDDataBuffer ";
DataModule1->show(sql,DataModule1->ADOQLEDDataBufferThirdShow1);
}
}
//将检索的数据更新到发送表,并将发送状态改为“未发送”
sql="update LEDSendData set SendData='"+DataModule1->ADOQLEDDataBufferThirdShow1->FieldByName("SendData")->AsString+"',\
FontColor='"+DataModule1->ADOQLEDDataBufferThirdShow1->FieldByName("Color")->AsString+"',\
Bufferid="+DataModule1->ADOQLEDDataBufferThirdShow1->FieldByName("ID")->AsString+",IsSend=0 \
where Showno="+DataModule1->ADOQLEDDataBufferThirdShow->FieldByName("ShowNo")->AsString;
DataModule1->exec(sql,DataModule1->ADOQLEDDataBufferThirdExec);
::Sleep(1000);
DataModule1->ADOQLEDDataBufferThirdShow->Next();
}
}
void __fastcall LEDDataBuffer::Execute()
{
//---- Place thread code here ----
//Timer1->OnTimer=Timer1Timer;
while(!Terminated)
{
Synchronize(ExecSQL);
::Sleep(10000);
}
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormShow(TObject *Sender)
{
//多LED刷新第一个页面
TimerPageChangeTimer(Sender);
LEDDataBufferThread->Resume();
}
//线程部分(里面的循环,每次循环都在2000数据左右)
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "LEDDataBufferUnit.h"
#include "datamodule.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// Important: Methods and properties of objects in VCL can only be
// used in a method called using Synchronize, for example:
//
// Synchronize(UpdateCaption);
//
// where UpdateCaption could look like:
//
// void __fastcall LEDDataBuffer::UpdateCaption()
// {
// Form1->Caption = "Updated in a thread";
// }
//---------------------------------------------------------------------------
__fastcall LEDDataBuffer::LEDDataBuffer(bool CreateSuspended)
: TThread(CreateSuspended)
{
//Timer1->Interval=10000;
}
//---------------------------------------------------------------------------
/*
void __fastcall LEDDataBuffer::Timer1Timer(TObject *Sender)
{
//Synchronize(ExecSQL);
}
*/
void __fastcall LEDDataBuffer::ExecSQL()
{
sql="select L.BufferID,T.* from (select showno,count(showno)as [Count] from LEDDataBuffer \
group by showno having count(showno) >1)T join LEDSendData L on T.ShowNo=L.ShowNo";
DataModule1->show(sql,DataModule1->ADOQLEDDataBufferThirdShow);
//循环检索这个区域在缓存的数据
while(!DataModule1->ADOQLEDDataBufferThirdShow->Eof)
{
//检索1--检索按照ID排序大约正在播放ID的数据
sql="select top 1* from LEDDataBuffer where ShowNo="+DataModule1->ADOQLEDDataBufferThirdShow->FieldByName("ShowNo")->AsString+" \
and ID>"+DataModule1->ADOQLEDDataBufferThirdShow->FieldByName("Bufferid")->AsString;
DataModule1->show(sql,DataModule1->ADOQLEDDataBufferThirdShow1);
//检索1---无结果--表示已经是最后一个了,要返回到第一个数据
if(DataModule1->ADOQLEDDataBufferThirdShow1->Eof)
{
//检索2---检索这个区域在缓存的第一个数据
sql="select top 1* from LEDDataBuffer where ShowNo="+DataModule1->ADOQLEDDataBufferThirdShow->FieldByName("ShowNo")->AsString+"\
order by ID asc";
DataModule1->show(sql,DataModule1->ADOQLEDDataBufferThirdShow1);
if(DataModule1->ADOQLEDDataBufferThirdShow1->Eof)
{
//检索2---无结果--表示已经是已经没有数据,返回空!!
sql="select top 1 0 as ID ,'' as ShowNo,'' as SendData,'红色' as Color from LEDDataBuffer ";
DataModule1->show(sql,DataModule1->ADOQLEDDataBufferThirdShow1);
}
}
//将检索的数据更新到发送表,并将发送状态改为“未发送”
sql="update LEDSendData set SendData='"+DataModule1->ADOQLEDDataBufferThirdShow1->FieldByName("SendData")->AsString+"',\
FontColor='"+DataModule1->ADOQLEDDataBufferThirdShow1->FieldByName("Color")->AsString+"',\
Bufferid="+DataModule1->ADOQLEDDataBufferThirdShow1->FieldByName("ID")->AsString+",IsSend=0 \
where Showno="+DataModule1->ADOQLEDDataBufferThirdShow->FieldByName("ShowNo")->AsString;
DataModule1->exec(sql,DataModule1->ADOQLEDDataBufferThirdExec);
::Sleep(1000);
DataModule1->ADOQLEDDataBufferThirdShow->Next();
}
}
void __fastcall LEDDataBuffer::Execute()
{
//---- Place thread code here ----
//Timer1->OnTimer=Timer1Timer;
while(!Terminated)
{
Synchronize(ExecSQL);
::Sleep(10000);
}
}
//---------------------------------------------------------------------------
#3
Synchronize(ExecSQL);的问题,应该把你ExecSQL函数中需要显示的数据保存在线程类的成员变量中,先直接调用ExecSQL获得数据,之后再用Synchronize调用另一个函数,这个函数负责根据在ExecSQL中设置的变量显示数据,如果数据量太多,可以考虑分成多次显示,在ExecSQL函数中,取得一批数据用Synchronize调用显示函数显示一次。你这样的做法相当于单线程
#4
倒地吐血不止,
你的线程里面只执行了sleep,ExecSQL因为Synchronize是在主线程执行了。
你试一试在线程里直接执行ExecSQL
你试一试在线程里直接执行ExecSQL
void __fastcall LEDDataBuffer::Execute()
{
while(!Terminated)
{
ExecSQL();
::Sleep(10000);
}
}
#5
楼上说的对,是的,虽然Synchronize是bcb提供的一个安全访问,但并不能使线程严格区分执行。4#的方法可以一试。不过我还是建议使用CreateThread创建线程:
CreateThread(NULL,0,ThreadProc,NULL,NULL,NULL);
第一个参数是指向安全属性的指针,NULL就行
第二个参数是初始线程堆栈大小,0就可以,WINDOWS会自动分配
第三个参数指向线程函数,必须是这样DWORD WINAPI ThreadProc (LPVOID pParam)
第四个参数是传给线程函数的参数,有就传,没有就NULL
第五个参数是线程启动方式,可以是挂起CREATE_SUSPENDED,或者马上启动NULL
最后一个参数是创建的线程ID。
成功的话,返回线程句柄。
CreateThread(NULL,0,ThreadProc,NULL,NULL,NULL);
第一个参数是指向安全属性的指针,NULL就行
第二个参数是初始线程堆栈大小,0就可以,WINDOWS会自动分配
第三个参数指向线程函数,必须是这样DWORD WINAPI ThreadProc (LPVOID pParam)
第四个参数是传给线程函数的参数,有就传,没有就NULL
第五个参数是线程启动方式,可以是挂起CREATE_SUSPENDED,或者马上启动NULL
最后一个参数是创建的线程ID。
成功的话,返回线程句柄。
#6
主线程只负责创建线程类,至于说是用CreateThread或者是用TThread类都可以。本质没有什么区别,推荐用Thread比较好,没有什么特殊用途的话很烦方便。
一般的做法是:
主线程创建线程类,热按后Resume() 在子线程中运行需要处理的函数,然后中间使用消息进行通讯。比如主线程需要显示一些子线程中的提示等,防止子线程出错而没法响应。
楼主的主要工作其实还是在主线程中执行,在执行数据操作的时候,主界面的消息循环处于等待状态,当然就会没有响应了。如果完全采用子线程操作,原则上来说只和cpu的处理能力有关了。
一般的做法是:
主线程创建线程类,热按后Resume() 在子线程中运行需要处理的函数,然后中间使用消息进行通讯。比如主线程需要显示一些子线程中的提示等,防止子线程出错而没法响应。
楼主的主要工作其实还是在主线程中执行,在执行数据操作的时候,主界面的消息循环处于等待状态,当然就会没有响应了。如果完全采用子线程操作,原则上来说只和cpu的处理能力有关了。
#1
详细说明你是怎么做的,别人才知道哪里出了问题。
我怀疑你其实用的是Timer而不是多线程。
我怀疑你其实用的是Timer而不是多线程。
#2
//主程序开始就启动线程
//线程部分(里面的循环,每次循环都在2000数据左右)
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "LEDDataBufferUnit.h"
#include "datamodule.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// Important: Methods and properties of objects in VCL can only be
// used in a method called using Synchronize, for example:
//
// Synchronize(UpdateCaption);
//
// where UpdateCaption could look like:
//
// void __fastcall LEDDataBuffer::UpdateCaption()
// {
// Form1->Caption = "Updated in a thread";
// }
//---------------------------------------------------------------------------
__fastcall LEDDataBuffer::LEDDataBuffer(bool CreateSuspended)
: TThread(CreateSuspended)
{
//Timer1->Interval=10000;
}
//---------------------------------------------------------------------------
/*
void __fastcall LEDDataBuffer::Timer1Timer(TObject *Sender)
{
//Synchronize(ExecSQL);
}
*/
void __fastcall LEDDataBuffer::ExecSQL()
{
sql="select L.BufferID,T.* from (select showno,count(showno)as [Count] from LEDDataBuffer \
group by showno having count(showno) >1)T join LEDSendData L on T.ShowNo=L.ShowNo";
DataModule1->show(sql,DataModule1->ADOQLEDDataBufferThirdShow);
//循环检索这个区域在缓存的数据
while(!DataModule1->ADOQLEDDataBufferThirdShow->Eof)
{
//检索1--检索按照ID排序大约正在播放ID的数据
sql="select top 1* from LEDDataBuffer where ShowNo="+DataModule1->ADOQLEDDataBufferThirdShow->FieldByName("ShowNo")->AsString+" \
and ID>"+DataModule1->ADOQLEDDataBufferThirdShow->FieldByName("Bufferid")->AsString;
DataModule1->show(sql,DataModule1->ADOQLEDDataBufferThirdShow1);
//检索1---无结果--表示已经是最后一个了,要返回到第一个数据
if(DataModule1->ADOQLEDDataBufferThirdShow1->Eof)
{
//检索2---检索这个区域在缓存的第一个数据
sql="select top 1* from LEDDataBuffer where ShowNo="+DataModule1->ADOQLEDDataBufferThirdShow->FieldByName("ShowNo")->AsString+"\
order by ID asc";
DataModule1->show(sql,DataModule1->ADOQLEDDataBufferThirdShow1);
if(DataModule1->ADOQLEDDataBufferThirdShow1->Eof)
{
//检索2---无结果--表示已经是已经没有数据,返回空!!
sql="select top 1 0 as ID ,'' as ShowNo,'' as SendData,'红色' as Color from LEDDataBuffer ";
DataModule1->show(sql,DataModule1->ADOQLEDDataBufferThirdShow1);
}
}
//将检索的数据更新到发送表,并将发送状态改为“未发送”
sql="update LEDSendData set SendData='"+DataModule1->ADOQLEDDataBufferThirdShow1->FieldByName("SendData")->AsString+"',\
FontColor='"+DataModule1->ADOQLEDDataBufferThirdShow1->FieldByName("Color")->AsString+"',\
Bufferid="+DataModule1->ADOQLEDDataBufferThirdShow1->FieldByName("ID")->AsString+",IsSend=0 \
where Showno="+DataModule1->ADOQLEDDataBufferThirdShow->FieldByName("ShowNo")->AsString;
DataModule1->exec(sql,DataModule1->ADOQLEDDataBufferThirdExec);
::Sleep(1000);
DataModule1->ADOQLEDDataBufferThirdShow->Next();
}
}
void __fastcall LEDDataBuffer::Execute()
{
//---- Place thread code here ----
//Timer1->OnTimer=Timer1Timer;
while(!Terminated)
{
Synchronize(ExecSQL);
::Sleep(10000);
}
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormShow(TObject *Sender)
{
//多LED刷新第一个页面
TimerPageChangeTimer(Sender);
LEDDataBufferThread->Resume();
}
//线程部分(里面的循环,每次循环都在2000数据左右)
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "LEDDataBufferUnit.h"
#include "datamodule.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// Important: Methods and properties of objects in VCL can only be
// used in a method called using Synchronize, for example:
//
// Synchronize(UpdateCaption);
//
// where UpdateCaption could look like:
//
// void __fastcall LEDDataBuffer::UpdateCaption()
// {
// Form1->Caption = "Updated in a thread";
// }
//---------------------------------------------------------------------------
__fastcall LEDDataBuffer::LEDDataBuffer(bool CreateSuspended)
: TThread(CreateSuspended)
{
//Timer1->Interval=10000;
}
//---------------------------------------------------------------------------
/*
void __fastcall LEDDataBuffer::Timer1Timer(TObject *Sender)
{
//Synchronize(ExecSQL);
}
*/
void __fastcall LEDDataBuffer::ExecSQL()
{
sql="select L.BufferID,T.* from (select showno,count(showno)as [Count] from LEDDataBuffer \
group by showno having count(showno) >1)T join LEDSendData L on T.ShowNo=L.ShowNo";
DataModule1->show(sql,DataModule1->ADOQLEDDataBufferThirdShow);
//循环检索这个区域在缓存的数据
while(!DataModule1->ADOQLEDDataBufferThirdShow->Eof)
{
//检索1--检索按照ID排序大约正在播放ID的数据
sql="select top 1* from LEDDataBuffer where ShowNo="+DataModule1->ADOQLEDDataBufferThirdShow->FieldByName("ShowNo")->AsString+" \
and ID>"+DataModule1->ADOQLEDDataBufferThirdShow->FieldByName("Bufferid")->AsString;
DataModule1->show(sql,DataModule1->ADOQLEDDataBufferThirdShow1);
//检索1---无结果--表示已经是最后一个了,要返回到第一个数据
if(DataModule1->ADOQLEDDataBufferThirdShow1->Eof)
{
//检索2---检索这个区域在缓存的第一个数据
sql="select top 1* from LEDDataBuffer where ShowNo="+DataModule1->ADOQLEDDataBufferThirdShow->FieldByName("ShowNo")->AsString+"\
order by ID asc";
DataModule1->show(sql,DataModule1->ADOQLEDDataBufferThirdShow1);
if(DataModule1->ADOQLEDDataBufferThirdShow1->Eof)
{
//检索2---无结果--表示已经是已经没有数据,返回空!!
sql="select top 1 0 as ID ,'' as ShowNo,'' as SendData,'红色' as Color from LEDDataBuffer ";
DataModule1->show(sql,DataModule1->ADOQLEDDataBufferThirdShow1);
}
}
//将检索的数据更新到发送表,并将发送状态改为“未发送”
sql="update LEDSendData set SendData='"+DataModule1->ADOQLEDDataBufferThirdShow1->FieldByName("SendData")->AsString+"',\
FontColor='"+DataModule1->ADOQLEDDataBufferThirdShow1->FieldByName("Color")->AsString+"',\
Bufferid="+DataModule1->ADOQLEDDataBufferThirdShow1->FieldByName("ID")->AsString+",IsSend=0 \
where Showno="+DataModule1->ADOQLEDDataBufferThirdShow->FieldByName("ShowNo")->AsString;
DataModule1->exec(sql,DataModule1->ADOQLEDDataBufferThirdExec);
::Sleep(1000);
DataModule1->ADOQLEDDataBufferThirdShow->Next();
}
}
void __fastcall LEDDataBuffer::Execute()
{
//---- Place thread code here ----
//Timer1->OnTimer=Timer1Timer;
while(!Terminated)
{
Synchronize(ExecSQL);
::Sleep(10000);
}
}
//---------------------------------------------------------------------------
#3
Synchronize(ExecSQL);的问题,应该把你ExecSQL函数中需要显示的数据保存在线程类的成员变量中,先直接调用ExecSQL获得数据,之后再用Synchronize调用另一个函数,这个函数负责根据在ExecSQL中设置的变量显示数据,如果数据量太多,可以考虑分成多次显示,在ExecSQL函数中,取得一批数据用Synchronize调用显示函数显示一次。你这样的做法相当于单线程
#4
倒地吐血不止,
你的线程里面只执行了sleep,ExecSQL因为Synchronize是在主线程执行了。
你试一试在线程里直接执行ExecSQL
你试一试在线程里直接执行ExecSQL
void __fastcall LEDDataBuffer::Execute()
{
while(!Terminated)
{
ExecSQL();
::Sleep(10000);
}
}
#5
楼上说的对,是的,虽然Synchronize是bcb提供的一个安全访问,但并不能使线程严格区分执行。4#的方法可以一试。不过我还是建议使用CreateThread创建线程:
CreateThread(NULL,0,ThreadProc,NULL,NULL,NULL);
第一个参数是指向安全属性的指针,NULL就行
第二个参数是初始线程堆栈大小,0就可以,WINDOWS会自动分配
第三个参数指向线程函数,必须是这样DWORD WINAPI ThreadProc (LPVOID pParam)
第四个参数是传给线程函数的参数,有就传,没有就NULL
第五个参数是线程启动方式,可以是挂起CREATE_SUSPENDED,或者马上启动NULL
最后一个参数是创建的线程ID。
成功的话,返回线程句柄。
CreateThread(NULL,0,ThreadProc,NULL,NULL,NULL);
第一个参数是指向安全属性的指针,NULL就行
第二个参数是初始线程堆栈大小,0就可以,WINDOWS会自动分配
第三个参数指向线程函数,必须是这样DWORD WINAPI ThreadProc (LPVOID pParam)
第四个参数是传给线程函数的参数,有就传,没有就NULL
第五个参数是线程启动方式,可以是挂起CREATE_SUSPENDED,或者马上启动NULL
最后一个参数是创建的线程ID。
成功的话,返回线程句柄。
#6
主线程只负责创建线程类,至于说是用CreateThread或者是用TThread类都可以。本质没有什么区别,推荐用Thread比较好,没有什么特殊用途的话很烦方便。
一般的做法是:
主线程创建线程类,热按后Resume() 在子线程中运行需要处理的函数,然后中间使用消息进行通讯。比如主线程需要显示一些子线程中的提示等,防止子线程出错而没法响应。
楼主的主要工作其实还是在主线程中执行,在执行数据操作的时候,主界面的消息循环处于等待状态,当然就会没有响应了。如果完全采用子线程操作,原则上来说只和cpu的处理能力有关了。
一般的做法是:
主线程创建线程类,热按后Resume() 在子线程中运行需要处理的函数,然后中间使用消息进行通讯。比如主线程需要显示一些子线程中的提示等,防止子线程出错而没法响应。
楼主的主要工作其实还是在主线程中执行,在执行数据操作的时候,主界面的消息循环处于等待状态,当然就会没有响应了。如果完全采用子线程操作,原则上来说只和cpu的处理能力有关了。