![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Работа с потоками [D7, WinXP]
den49 © (2009-10-06 15:40:00)Здравствуйте, подскажите пожалуйста что в коде не так. НАдо создать поток через CreateThread, который прочитает текстовый файл.(потом его надо сравнить с другим и вывести результаты сравнения, но сейчас это не важно.) для передачи созданному потоку 2 переменных(по-другому не придумал) делаю структуру и в ней передаю. Но выдает ошибку при запуске потока: access vialation at ...: write of address...
Код:
type
TThread_Value = record
component:TMemo;
filename:string;
end;
.....
var
Form1: TForm1;
GetFile:THandle;
ThreadID1,:Cardinal;
Thread_Value1:TThread_Value;
implementation
{$R *.dfm}
procedure SetText(Thread_ValueN:TThread_Value); stdcall;
Var f:TextFile;
st:String;
begin
AssignFile(f,Thread_ValueN.filename);
Reset(f);
if IOResult0 then
begin
ShowMessage('Îøèáêà îòêðûòèÿ ôàéëà ' + Thread_ValueN.filename);
Exit;
end;
While not EOF(f) do
begin
ReadLn(f,st);
end;
Thread_ValueN.component.Lines.LoadFromFile(Thread_ValueN.filename);
CloseFile(f);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Opendialog1.Execute;
Thread_Value1.filename:=OpenDialog1.FileName;
Thread_Value1.component:=Memo1;
GetFile := CreateThread(NIL, 0, @SetText, @Thread_Value1, 0, ThreadID1);
end;
end.
den49 (2009-10-08 23:19:00) [1]
> Еще есть стандартный класс TThread.
C TThread сначала написал, программа полностью выполняла условия задачи, но препод сказал, что надо с использование не стандартных классов, а с WinApi. Поэтому начал с этим всем морочиться)
Loginov Dmitry (2009-10-08 22:10:00) [2]>
> Так пробовал, программа не компилируется на знаке ^ выдает
> ошибку: Identifier expected but ^ found.
Объяви структуру и указатель на нее вот так:
PThread_Value = ^TThread_Value;
TThread_Value = record
component:TMemo;
filename:string;
end;
Объяви процедуру вот так:
procedure SetText(Thread_ValueN: PThread_Value); stdcall;
Тогда все скомпилится.
AssignFile в потоке писать можно?
AssignFile ничего не делает, кроме как инициализирует поля заданной
файловой переменной. Другое дело, что дельфевые функции открытия файла
(reset, append) обращаются к глобальной переменной FileMode, которая
определяет режим открытия файла. Поэтому с режимами этими особо не
разгуляешься, хотя иногда нужны другие режимы открытия. Поэтому [7] :)
> Вот с ним всё ясно и понятно.
Еще есть стандартный класс TThread. Имхо, с ним работать проще.
По крайней мере не нужно каждый раз вспоминать прототип процедуры
потока и назначение каждого из параметров функции BeginThread().
Как бы то ни было, требуемый результат можно получить любым из
способов - главное чтобы он был наиболее знаком.
DVM (2009-10-08 22:02:00) [3]
> А в CreateThread баги какие-то ..?
Напиши до CreateThread строку IsMultiThread := true и будет почти то же самое.
Leonid Troyanovsky (2009-10-08 20:09:00) [4]
> den49 © (08.10.09 19:48) [13]
> Во, спасибо большое. Вот с ним всё ясно и понятно. А в CreateThread
> баги какие-то ..?
See also: BeginThread.
--
Regards, LVT.
den49 (2009-10-08 19:48:00) [5]Во, спасибо большое. Вот с ним всё ясно и понятно. А в CreateThread баги какие-то ..?
Leonid Troyanovsky (2009-10-08 18:44:00) [6]
> den49 © (08.10.09 18:38) [11]
> Может объект вместо структуры юзать?
BeginThread forever.
Уже ж советовали.
--
Regards, LVT.
den49 (2009-10-08 18:38:00) [7]По синхронизации понятно, а что мне с передачей в поток структуры делать,немогу от ошибки избавиться( Что посоветуете? Может объект вместо структуры юзать?
Leonid Troyanovsky (2009-10-08 18:08:00) [8]
> DVM © (08.10.09 17:52) [9]
> Там можно делать что угодно
Я б за потроха AssignFile &etc зуб не дал.
Смутно помнятся какие-то грабли с потоком
в конольном приложении, делающим Write..
правда, в stdout.
Ну, и, в любом случае, BeginThread forever.
--
Regards, LVT.
DVM (2009-10-08 17:52:00) [9]
> den49 © (08.10.09 17:36) [5]
> AssignFile в потоке писать можно?
Там можно делать что угодно, главное не обращаться к одним и тем же переменным, объектам и т.д. одновременно из двух и более потоков без синхронизации.
Leonid Troyanovsky (2009-10-08 17:49:00) [10]
> den49 © (08.10.09 17:43) [6]
> То есть создать еще один поток и в нем Мемо присвоить текст?
Гы.
SendMessage(Memo.Handle, EM_SETSELTEXT, ..)
Но, тут тоже есть тонкость, бо такой код небезопасен, f.e.
если Memo нет, или у него еще/уже нет хендла.
Так что - synchronize forever.
--
Regards, LVT.
Leonid Troyanovsky (2009-10-08 17:45:00) [11]
> den49 © (08.10.09 17:36) [5]
> вопрос как отличать процедуры исп. VCL? AssignFile в потоке
> писать можно?
TFileStream forever.
--
Regards, LVT.
den49 (2009-10-08 17:43:00) [12]
> Передавать то можно, но вот обращаться к нему из вторичного
> потока не рекомендуется без синхронизации.
То есть создать еще один поток и в нем Мемо присвоить текст?
den49 (2009-10-08 17:36:00) [13]За замечания на счет синхронизации спасибо, но напрашивается вопрос как отличать процедуры исп. VCL? AssignFile в потоке писать можно?
DVM (2009-10-08 17:34:00) [14]
> den49 © (08.10.09 17:30) [3]
> Хочу использовать один поток для работы с 2 файлами, для
> этого передаю компонент TMemo.
Передавать то можно, но вот обращаться к нему из вторичного потока не рекомендуется без синхронизации.
den49 (2009-10-08 17:30:00) [15]
> В CreateThread() передаешь указатель на структуру Thread_Value1,
> однако в функции SetText() работаешь не с указателем, а
> с самойструктурой. Попробуй объявить процедуру вот так:procedure
> SetText(Thread_ValueN: ^TThread_Value); stdcall;
Так пробовал, программа не компилируется на знаке ^ выдает ошибку: Identifier expected but ^ found.
> > TThread_Value = record> component:TMemo;> filename:
> string;> end;Что там делает TMemo?
Хочу использовать один поток для работы с 2 файлами, для этого передаю компонент TMemo.
Loginov Dmitry (2009-10-06 21:29:00) [16]> Но выдает ошибку при запуске потока: access vialation at
> ...: write of address...
В CreateThread() передаешь указатель на структуру Thread_Value1,
однако в функции SetText() работаешь не с указателем, а с самой
структурой. Попробуй объявить процедуру вот так:
procedure SetText(Thread_ValueN: ^TThread_Value); stdcall;
> ShowMessage('Ioeaea ioe?uoey oaeea ' + Thread_ValueN.filename)
> ;
Нельзя вызывать ShowMessage из допольнительных потоков. ShowMessage для
показа окна использует VCL, а к VCL нельзя обращаться из доп. потоков напрямую.
> Thread_ValueN.component.Lines.LoadFromFile(Thread_ValueN.filename)
> ;
Так тоже нельзя делать, ибо VCL.
Используй Syncronize либо другие методы синхронизации.
Об этом в интернете можно найти очень много статей.
DVM (2009-10-06 16:08:00) [17]
> TThread_Value = record
> component:TMemo;
> filename:string;
> end;
Что там делает TMemo?