Цитата:
Сообщение от Alex_4444
Может я не правильно понял задачу. Я видел лишь попытку разбора дерева, а что делается с листьями? Куда ложатся данные? Если в одно и то же место - следует ли учесть порядок данных? и т.д.
|
В конечном итоге я всё разобрал. Мне одноуровневого разбиения на потоки достаточно.
Глубже нет смысла разбивать. Листья складируются в ADODataSet (MySQL таблица) созданный каждый в своём потоке.
Работает всё ужасно не стабильно и криво. Сейчас я сохраняю каждую ветку XML в массив.
Передаю определённую элемент массива в поток, и кладу этот поток в другой массив (определённо длины).
Пока первый массив не иссякнет так и гоняю.
Время от времени появляются ошибки доступа к памяти.
И что-то мне подсказывает, что нельзя таким образом работать с объектом XMLDocument.
Код:
FormMain.XMLDoc.FileName := LOKAL_DIR + 'XML\' + FileName;
FormMain.XMLDoc.Active := true;
Objects := FormMain.XMLDoc.DocumentElement;
SetLength(ObjectsArr, Objects.ChildNodes.Count);
for ObjNr := 0 to Objects.ChildNodes.Count - 1 do
ObjectsArr[ObjNr] := Objects.ChildNodes[ObjNr];
while Length(ObjectsArr) > 0 do
for ObjNr := 0 to 4 do
if (ParsersArr[ObjNr] = nil) or (ParsersArr[ObjNr].Finished) then
begin
temp := Length(ObjectsArr) - 1;
ParsersArr[ObjNr] := TParser.Create(ObjectsArr[temp]);
SetLength(ObjectsArr, (Length(ObjectsArr) - 1));
end;
Кто-нибудь может объяснить, как воспользоваться конструкцией для создания Очереди задач?
Код:
function TForm1.DoWorkForQueue(aQueue: TThreadList): boolean;
begin
with aQueue.LockList do
try
Result := not(Count = 0);
finally
aQueue.UnlockList;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Queue: TThreadList;
Pool: TThreadList;
objNo: integer;
const
MaxThreadCount = 5;
begin
Queue := TThreadList.Create;
try
for objNo := 0 to XMLDoc.DocumentElement.ChildNodes.Count - 1 do
Queue.Add(XMLDoc.DocumentElement.ChildNodes[objNo]); // Ошибка соответствия Типов TPointer и IXMLNode
while DoWorkForQueue(Queue) do
begin
Pool := TThreadList.Create;
with Pool.LockList do
try
if Count < MaxThreadCount then
Add(TXmlToSql.Create(Queue));
finally
Pool.UnlockList;
end;
end;
finally
Queue.Free;
end;
end;
Я понять не могу как передать TPointer на кусок XML'я в TThreadList.
Imlike, к вам ещё вопрос:
Стоит ли хранить потоки в таком же списке для их "подсчёта"?
Или просто завести глобальную переменную для их подсчёта (инкрементировать при создании, и декрементировать при уничтожении потока)