Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.11.22;
Скачать: CL | DM;

Вниз

Работа с потоками   Найти похожие ветки 

 
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("&#206;&#248;&#232;&#225;&#234;&#224; &#238;&#242;&#234;&#240;&#251;&#242;&#232;&#255; &#244;&#224;&#233;&#235;&#224; " + 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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.013 c
15-1253880513
Kerk
2009-09-25 16:08
2009.11.22
Рабсила vs труд


2-1254932240
Johnnnnn
2009-10-07 20:17
2009.11.22
Сменить директорию диалога Open?


15-1253621448
Артур Пирожков
2009-09-22 16:10
2009.11.22
Можно ли записать радио?


15-1253781647
@!!ex
2009-09-24 12:40
2009.11.22
В Москве экспериментируют с солнечной энергией


2-1254797177
Серый
2009-10-06 06:46
2009.11.22
как распечатать запрос Adoquery