Форум: "Начинающим";
Текущий архив: 2009.11.22;
Скачать: [xml.tar.bz2];
ВнизРабота с потоками Найти похожие ветки
← →
den49 © (2009-10-06 15:40) [0]Здравствуйте, подскажите пожалуйста что в коде не так. НАдо создать поток через 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 IOResult<>0 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.
← →
DVM © (2009-10-06 16:08) [1]
> TThread_Value = record
> component:TMemo;
> filename:string;
> end;
Что там делает TMemo?
← →
Loginov Dmitry © (2009-10-06 21:29) [2]> Но выдает ошибку при запуске потока: 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 либо другие методы синхронизации.
Об этом в интернете можно найти очень много статей.
← →
den49 © (2009-10-08 17:30) [3]
> В 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.
← →
DVM © (2009-10-08 17:34) [4]
> den49 © (08.10.09 17:30) [3]
> Хочу использовать один поток для работы с 2 файлами, для
> этого передаю компонент TMemo.
Передавать то можно, но вот обращаться к нему из вторичного потока не рекомендуется без синхронизации.
← →
den49 © (2009-10-08 17:36) [5]За замечания на счет синхронизации спасибо, но напрашивается вопрос как отличать процедуры исп. VCL? AssignFile в потоке писать можно?
← →
den49 © (2009-10-08 17:43) [6]
> Передавать то можно, но вот обращаться к нему из вторичного
> потока не рекомендуется без синхронизации.
То есть создать еще один поток и в нем Мемо присвоить текст?
← →
Leonid Troyanovsky © (2009-10-08 17:45) [7]
> den49 © (08.10.09 17:36) [5]
> вопрос как отличать процедуры исп. VCL? AssignFile в потоке
> писать можно?
TFileStream forever.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2009-10-08 17:49) [8]
> den49 © (08.10.09 17:43) [6]
> То есть создать еще один поток и в нем Мемо присвоить текст?
Гы.
SendMessage(Memo.Handle, EM_SETSELTEXT, ..)
Но, тут тоже есть тонкость, бо такой код небезопасен, f.e.
если Memo нет, или у него еще/уже нет хендла.
Так что - synchronize forever.
--
Regards, LVT.
← →
DVM © (2009-10-08 17:52) [9]
> den49 © (08.10.09 17:36) [5]
> AssignFile в потоке писать можно?
Там можно делать что угодно, главное не обращаться к одним и тем же переменным, объектам и т.д. одновременно из двух и более потоков без синхронизации.
← →
Leonid Troyanovsky © (2009-10-08 18:08) [10]
> DVM © (08.10.09 17:52) [9]
> Там можно делать что угодно
Я б за потроха AssignFile &etc зуб не дал.
Смутно помнятся какие-то грабли с потоком
в конольном приложении, делающим Write..
правда, в stdout.
Ну, и, в любом случае, BeginThread forever.
--
Regards, LVT.
← →
den49 © (2009-10-08 18:38) [11]По синхронизации понятно, а что мне с передачей в поток структуры делать,немогу от ошибки избавиться( Что посоветуете? Может объект вместо структуры юзать?
← →
Leonid Troyanovsky © (2009-10-08 18:44) [12]
> den49 © (08.10.09 18:38) [11]
> Может объект вместо структуры юзать?
BeginThread forever.
Уже ж советовали.
--
Regards, LVT.
← →
den49 © (2009-10-08 19:48) [13]Во, спасибо большое. Вот с ним всё ясно и понятно. А в CreateThread баги какие-то ..?
← →
Leonid Troyanovsky © (2009-10-08 20:09) [14]
> den49 © (08.10.09 19:48) [13]
> Во, спасибо большое. Вот с ним всё ясно и понятно. А в CreateThread
> баги какие-то ..?
See also: BeginThread.
--
Regards, LVT.
← →
DVM © (2009-10-08 22:02) [15]
> А в CreateThread баги какие-то ..?
Напиши до CreateThread строку IsMultiThread := true и будет почти то же самое.
← →
Loginov Dmitry © (2009-10-08 22:10) [16]>
> Так пробовал, программа не компилируется на знаке ^ выдает
> ошибку: 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().
Как бы то ни было, требуемый результат можно получить любым из
способов - главное чтобы он был наиболее знаком.
← →
den49 © (2009-10-08 23:19) [17]
> Еще есть стандартный класс TThread.
C TThread сначала написал, программа полностью выполняла условия задачи, но препод сказал, что надо с использование не стандартных классов, а с WinApi. Поэтому начал с этим всем морочиться)
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.11.22;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.007 c