![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Зачем-то глючат нити... Хотя не должны... [D6, Win2k]
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м