Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Зачем-то глючат нити... Хотя не должны... [D6, Win2k]


Страницы:   1 2

alxx ©   (2002-06-21 10:25:00) 

У меня на форме лежит Memo1. При изменении его (OnChange) у меня запускается Thread и делает кой-какую работенку - допустим считает до десяти тысяч. И вот она - эта программа виснет примерно на 1 из 100 нажатий на клавишу в Memo1 (Access violation error). Кто-нибудь может мне помочь, а то у меня уже крыша едет, чего только не перепробовал. Исходники здесь:


Const WM_ProcessDONE = wm_User+0;

type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure OnProcessDone(Var msg:TMessage); message WM_PROCESSDONE;
procedure Memo1Change(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Running :Boolean;
NeedToRun:Boolean;
Expr :String;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

Function ThreadFunc(P:Pointer):LongInt; stdcall;
Var
i: INteger;
DC:HDC;
S:String;
Begin
/////////////////////////////////
DC:=GetDC(Form1.Handle);
for i:=0 to 10000 do
Begin
s:=intToStr(i);
TextOut(DC,10,10,PChar(S),Length(S));
End;
ReleaseDC(Form1.Handle,DC);
//////////////////////////////////
Form1.Running:=False;

// PostMessage(Form1.Handle, WM_PROCESSDONE,0,0);
End;

procedure TForm1.FormCreate(Sender: TObject);
begin
Running:=False;
NeedToRun:=False;
end;

procedure TForm1.OnProcessDone(Var msg:TMessage);
var hThread:THandle;
ThreadID:DWord;
Begin
if Form1.NeedToRun Then
Begin
If not Running Then
Begin
hThread:=CreateThread(nil,
0,
@ThreadFunc,
nil,
0,
ThreadID);
Running:=True;
NeedToRun:=False;
End;
End;
End;



procedure TForm1.Memo1Change(Sender: TObject);
var hThread:THandle;
ThreadID:DWord;
Expr1:String;
i:Integer;
begin

Expr1:="";
For i:=0 to RE.Lines.Count-1 do Expr1:=Expr1+RE.Lines.Strings[i];
If Expr1<>Expr Then
Begin
Expr:=Expr1;
If not Running Then
Begin
hThread:=CreateThread(nil,
0,
@ThreadFunc,
nil,
0,
ThreadID);
SetThreadPriority(hThread,THREAD_PRIORITY_BELOW_NORMAL);
Running:=True; {}
End Else NeedToRun:=True;
End;
{}
end;


kull   (2002-06-21 12:40:00) [21]

И я так понимаю что при каждом OnChange надо старый поток уничтожать, а новый запускать, чтобы несколько потоков не интерпретировали одновременно.


kull   (2002-06-21 12:37:00) [22]

А ты делаешь FreeOnTerminate = True ?


alxx   (2002-06-21 12:35:00) [23]

Может, кто-нибудь может показать примерчик, заведомо работающий?
Что-то я совсем уже запарился...


alxx   (2002-06-21 12:33:00) [24]

> Digitman
Ну у меня обработка строк происходит при изменении. Что-то типа интерпретатора. Но даже просто посчитать до 10000 не получается.

> Dapo
Переделал я под TThread, но зависает она все равно периодически.
Блин...


Dapo   (2002-06-21 12:18:00) [25]

С потоками с помощью API не работал. Это и не к чему, по крайней мере в решении твоей проблемы. Используй TThread. Люди правильно говорят. Если у тебя поток только считает, и не использует VCL то его и синхронизировать не надо.
unit Unit2;

interface

uses
Classes;

type
MyThread = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;

implementation

{ MyThread }

procedure MyThread.Execute;
var i:integer;
j:real;
begin
While not Terminated do
begin
{ Пиши сюда свои вычисления }
j:=i+10 ;
If j>10000 then Terminate;
end;
end;

end.
В Memo1.OnChange:

var Mythread:TMyThread;
....
//Проверь запущен или нет, если нет
MyThread:=TMyThread.Create(false);
....
end;


Digitman   (2002-06-21 11:28:00) [26]

>alxx

А каков вообще смысл всего этого ?


kull   (2002-06-21 10:50:00) [27]

Почему же, помогает.
Делает работу более удобной.

Избавляет от ненужной рутины типа возни с Handle - ми, вызовов API - шных функций и т.п. для того он и сделан.

А если нет синхронизации, то и TThread не поможет.


alxx   (2002-06-21 10:41:00) [28]

Класс TThread тоже не помогает...


alxx   (2002-06-21 10:40:00) [29]

Синхронизации конечно нет, но я TextOut убираю и все равно проблемы остаются...
А вот с какими потоками я должен синхронизировать - у меня же он один (мой). Как же быть то?


kull   (2002-06-21 10:38:00) [30]

А почему не использовать класс TThread.


Digitman   (2002-06-21 10:37:00) [31]

1. TextOut() - не thread-safe ф-ция.
2. У тебя напрочь отсутствует синхронизация между потоками


alxx   (2002-06-21 10:29:00) [32]

Там только в Memo1Change - не RE.Lines надо, а Memo1.Lines - это я по частям выдергивал - перепутал с RichEdit"oм


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо