100分,多线程问题!

Lersh 2002-06-13 07:35:31
为什么我用了多线程了,运行期间窗体还是没有没有响应?代码如下:
void __fastcall SearchThread::Execute()
{
Synchronize((TThreadMethod)&SearchDate); //是不是这里的问题?但不用Synchronize会出错。
}
//---------------------------------------------------------------------------

void __fastcall SearchThread::SearchDate()
{
Form1->Query->Params->ParamByName("StartDate")->Value=StrToDate(Form1->Edit2->Text);
Form1->Query->Params->ParamByName("EndDate")->Value=StrToDate(Form1->Edit3->Text);
Form1->Query->Open();
Form1->Query->First();
int Nor=0,GG=0;
while(!Form1->Query->Eof)
{

Form1->Gonggao->Items->Add(Form1->Query->FieldByName("title")->Value);

}

Query是TClientDataSet。
...全文
27 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
sncel 2002-06-15
  • 打赏
  • 举报
回复
自由线程中不能使用OlE库,我看了Borland中解决这个问题的方法,但是没有用,我也找不到一下子的解决方法,等找到了我会和你联系的。
tiger_qi 2002-06-14
  • 打赏
  • 举报
回复
关注,我也要用到多线成了
sncel 2002-06-14
  • 打赏
  • 举报
回复
看看我的代码,我已应用在程序中了,没有问题。
//在Project1.cpp中
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "axctrls.hpp"
//---------------------------------------------------------------------------
USEFORM("Unit1.cpp", Form1);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{ CoInitFlags=COINIT_MULTITHREADED; //加入这句
Application->Initialize();
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
//---------------------------------------------------------------------------

//在Unit1.cpp中
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include "comObj.hpp"
#include "Unit1.h"
#include "axctrls.hpp"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "DBGridEh"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
DWORD WINAPI CreateSysTree(LPVOID p)
{
TClientDataSet *GetTag=new TClientDataSet(NULL);
GetTag->RemoteServer=Form1->DCOMConnection1;
GetTag->ProviderName="LocalDataSet";
GetTag->PacketRecords=100;
Form1->DataSource1->DataSet=GetTag;
GetTag->CommandText="select * from TabCpslb ";
GetTag->Open();
//你可以在这下里加入你需要的代码。。。。
return true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HANDLE CSysThread;
DWORD CSysID;
CSysThread=CreateThread(0,0,(LPTHREAD_START_ROUTINE)CreateSysTree,0,0,&CSysID);
CloseHandle(CSysThread);

}
//---------------------------------------------------------------------------
如果还不行,请联系我。
短歌如风 2002-06-14
  • 打赏
  • 举报
回复
什么样的冲突?
Lersh 2002-06-14
  • 打赏
  • 举报
回复
对了!!!!

plainsong(伤心的风)你太强了,我爱死你了~~~~~~~~~~~(开玩笑,不要当真:))
Lersh 2002-06-14
  • 打赏
  • 举报
回复
plainsong(伤心的风)怎么在动态生成的ClientDataSet里添加Params?
Lersh 2002-06-14
  • 打赏
  • 举报
回复
CoInitFlags = COINIT_MULTITHREAD;不对啊,查不到
sncel 2002-06-14
  • 打赏
  • 举报
回复
plainsong(伤心的风) 的应该可以实现。
bcb_fans 2002-06-14
  • 打赏
  • 举报
回复
不服,再试:-)

1、先定义一个临时的TTimer变量;
2、在按纽脚本中启动定时器
__fastcall void Button1OnClick(TObject* Sender)
{
Timer1->Interval=100;//立即启动
Timer1->Enabled=true;
}
3、在定时器脚本中建立查询线程:
__fastcall void Timer1OnTimer(TObject* Sender)
{
Timer1->Enabled=false;
//建立查询线程...同下
}
这样查询线程和主线程彻底不相关了,主窗口应该可以响应了吧.

-----------
如果仅仅从多线程的方面来考虑,问题应该不难:

void __fastcall QueryFunc();

//准备查询
HANDLE hThread;

hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)QueryFunc,(LPVOID)ppDeleteParam[i],CREATE_SUSPENDED,
&ThreadID);

//启动线程,这时查询线程运行,但主线程也在运行,所以主窗口仍然能响应消息.
ResumeThread(hThread);

CloseHandle(hTread);

-------
void __fastcall QueryFunc()
{
Form1->Query->Params->ParamByName("StartDate")->Value=StrToDate(Form1->Edit2->Text);
Form1->Query->Params->ParamByName("EndDate")->Value=StrToDate(Form1->Edit3->Text);
Form1->Query->Open();
Form1->Query->First();
int Nor=0,GG=0;
while(!Form1->Query->Eof)
{
Form1->Gonggao->Items->Add(Form1->Query->FieldByName("title")->Value);

}

}

短歌如风 2002-06-14
  • 打赏
  • 举报
回复
为你的SearchThread加一个成员变量:
TClientDataSet* FQuery;
如果是用的SocketConnection,把它的supportcallbacks属性设置为false;
如果是用的DCOMConnection,在WinMain中在Application->Initialize();前加一句CoInitFlags = COINIT_MULTITHREAD;(应该是在ComObj.hpp中,记不太清了,变量和常量名可能会写错,你查一下)。
然后如下改一下,把在Synchronize中执行的语句限制在最少:
void __fastcall SearchThread::Execute()
{
FQuery = new TClinetDataSet(NULL);
//设置FQuery的属性。
FQuery->Params->ParamByName("StartDate")->Value=StrToDate(Form1->Edit2->Text);
FQuery->Params->ParamByName("EndDate")->Value=StrToDate(Form1->Edit3->Text);
FQuery->Open();
FQuery->First();
int Nor=0,GG=0;
while(!FQuery->Eof)
{

Synchronize((TThreadMethod)&SearchDate
FQuery -> Next();

}
//---------------------------------------------------------------------------

void __fastcall SearchThread::SearchDate()
{

Form1->Gonggao->Items->Add(Form1->Query->FieldByName("title")->Value);

}
JXLEE365 2002-06-14
  • 打赏
  • 举报
回复
Synchronize((TThreadMethod)&SearchDate);
这句应改为Synchronize(SearchDate);

Form1->Query->Params->ParamByName("StartDate")->Value=StrToDate(Form1->Edit2->Text);
我用的是Parameters而不是Params

while(!Form1->Query->Eof)
循环中应该有Form1->Query->Next()语句,否则如果Form1->Query中
有记录的话,就是一个死循环。
Lersh 2002-06-14
  • 打赏
  • 举报
回复
CoInitFlags=COINIT_MULTITHREADED;和CppWebBrowser冲突啊
Lersh 2002-06-13
  • 打赏
  • 举报
回复
有没有高人啊?
bcb_fans 2002-06-13
  • 打赏
  • 举报
回复
嘿嘿,不不好意思,上面是瞎说,就当我没说.
bcb_fans 2002-06-13
  • 打赏
  • 举报
回复
如果仅仅从多线程的方面来考虑,问题应该不难:

void __fastcall QueryFunc();

//准备查询
HANDLE hThread;

hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)QueryFunc,(LPVOID)ppDeleteParam[i],CREATE_SUSPENDED,
&ThreadID);

//启动线程,这时查询线程运行,但主线程也在运行,所以主窗口仍然能响应消息.
ResumeThread(hThread);

CloseHandle(hTread);

-------
void __fastcall QueryFunc()
{
Form1->Query->Params->ParamByName("StartDate")->Value=StrToDate(Form1->Edit2->Text);
Form1->Query->Params->ParamByName("EndDate")->Value=StrToDate(Form1->Edit3->Text);
Form1->Query->Open();
Form1->Query->First();
int Nor=0,GG=0;
while(!Form1->Query->Eof)
{
Form1->Gonggao->Items->Add(Form1->Query->FieldByName("title")->Value);

}

}
Lersh 2002-06-13
  • 打赏
  • 举报
回复
的确是SQL语句查询时很费时间,也就是说Query->Open();这一句很费时间,导致程序没有反应。但我怎么在这句里加Application->ProcessMessages();我又不能进入Query->Open的循环里
wyb_Ultra 2002-06-13
  • 打赏
  • 举报
回复
用Application->ProcessMessages();会有很多不尽人意的地方,比如说,把鼠标点击一下菜单,然后不动,程序就会一直响应鼠标事件,不会往下工作了。
Lersh 2002-06-13
  • 打赏
  • 举报
回复
难道远程数据库查询就不能用多线程了?
我不懂电脑 2002-06-13
  • 打赏
  • 举报
回复
线程Sleep()或用2缓冲或用TThreadList
jishiping 2002-06-13
  • 打赏
  • 举报
回复
不会吧。我想可能是你的SQL语句查询时很费时间,也就是说Query->Open();
这一句很费时间,导致程序没有反应。如果这样的话,还是放到一个多线程
里吧,只是在多线程的函数里,一样添加Application->ProcessMessages();
加载更多回复(16)

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧