多线程,动态创建的控件竟然必须放到Synchronize里面执行,为什么呢。没道理啊!
void __fastcall TChaXunThread::Execute()
{
retnum = 6;
try
{
char cuser[MAX_PATH] = "";
char cpass[MAX_PATH] = "";
strcpy(cuser, user.c_str());
strcpy(cpass, pass.c_str());
if(filepath.SubString(1, 2) == "\\\\")
{
DWORD retcode = NetConnect2(ExtractFileDir(filepath).c_str(), cuser, cpass);
if(retcode == 0)
{
if(FileExists(filepath))
{
retnum = 1;
if(ExtractFileExt(filepath).LowerCase() == ".dbf" && !sqltxt.Trim().IsEmpty())
{
String filename = ChangeFileExt(ExtractFileName(filepath), "");
TDbf *DbfThread;
DbfThread = new TDbf(NULL);
DbfThread->Active = false;
DbfThread->TableName = filepath;
DbfThread->ReadOnly=true;
DbfThread->Active = true;
TxQuery *xQueryThread;
xQueryThread = new TxQuery(NULL);
xQueryThread->DataSets->Clear();
xQueryThread->AddDataSet(DbfThread, filename);
xQueryThread->SQL->Clear();
xQueryThread->SQL->Text = sqltxt;
xQueryThread->Open(); //这句Open的语句,必须用Synchronize放到主线程执行否则报错。为什么呢。我这里明明是动态创建的。
retStr = "有" + IntToStr(xQueryThread->RecordCount) + "条,点击查看明细";
//delete DbfThread, xQueryThread;
}
}
else {
retnum = 2;
}
}
if(retcode == 1326)
{
retnum = 4;
}
if(retcode == 1219)
{
retnum = 7;
}
}
else {
if(FileExists(filepath))
{
retnum = 1;
}
else
{
retnum = 2;
}
}
}
catch(...)
{
retnum = 5;
// throw;
}
Synchronize(UpdateChaXunGrid);
}
[解决办法]
创建线程单元的时候系统有提示撒,线程中访问VCL对象的属性和方法要用Synchronize。
[解决办法]
线程中同步访问VCL资源就得这么写了
[解决办法]
楼主这种用法我原来也这么用过,那个open不是必须要到Synchronize里面执行得,你这个控件其实就是查询了数据库,并没用操作界面和vcl控件属性.你如果不放到Synchronize这个里面是个什么情况??再一个你这段代码主要完成什么功能?
[解决办法]
你这个错误产生的根本原因应该是同时操作同一个dbf文件所致,bdf文件应该是不支持多用户的,是不是这个地方有问题.你每个线程操作的dbf文件是同一个么,如果是同一个就估计是这个问题了.