Форум: "WinAPI";
Текущий архив: 2007.03.11;
Скачать: [xml.tar.bz2];
ВнизProcessMessages Найти похожие ветки
← →
dmirror (2006-10-31 14:08) [0]В чистом приложении вызов Application.processmessages работает.
Создаю поток
type
TServiceThread = class(TThread)
public
procedure Execute; override;
end;
---
var
ServiceThread: TServiceThread;
и на processmessages компилятор начинает ругаться что не видит такой функции.
что может быть и как исправить?
← →
Eraser © (2006-10-31 14:13) [1]> [0] dmirror (31.10.06 14:08)
> и на processmessages компилятор начинает ругаться что не
> видит такой функции.
код показываей, где ругается.
ЗЫ
не вздумай вызывать processmessages из доп. потока.
← →
Сергей М. © (2006-10-31 14:14) [2]processmessages - это не функция, а процедурный метод объекта класса TApplication.
← →
YuRock © (2006-10-31 15:55) [3]
> Eraser © (31.10.06 14:13) [1]
>
> ЗЫ
> не вздумай вызывать processmessages из доп. потока.
>
Почему?
← →
Ketmar © (2006-10-31 16:02) [4]>[3] YuRock(c) 31-Oct-2006, 15:55
>Почему?
поверь на слово пока. ибо это с 1917 года надо про шпингалеты пояснять.
← →
YuRock © (2006-10-31 16:05) [5]
> поверь на слово пока. ибо это с 1917 года надо про шпингалеты
> пояснять.
Хорошо. Я тогда тоже дам совет. Не пользуйся никогда компонентом TButton. Почему? Поверь на слово - я знаю, почему...
← →
Ketmar © (2006-10-31 16:10) [6]>[5] YuRock(c) 31-Oct-2006, 16:05
ещё один надмозг. сезон, что ли? игнор.
← →
Eraser © (2006-10-31 16:13) [7]> [3] YuRock © (31.10.06 15:55)
> Почему?
Зачем?
Зачем понадобилось вызывать ProcessMessages в доп. потоке?
Нельзя вызывать, потому что ProcessMessages позволяет перейти к обработке всей очереди сообщений основного потока приложения, тем самым прервав выполнение кода в основном же потоке, до тех пор, пока метод ProcessMessages не выполнится.
Если вызвать ProcessMessages из доп. потока, то программа или этот поток, в лучшем случае, скорее всего подвиснут.
← →
Сергей М. © (2006-10-31 16:17) [8]
> YuRock © (31.10.06 15:55) [3]
> Почему?
Дурацкий вопрос.
Ну, если желаешь ответ на него, то хотя бы потому что поле TApplication.FTerminate не защищено крит.секцией. И при этом нет никаких гарантий, что потоку не послано WM_QUIT.
Смотреть и изучать исходники класса TApplication до полного просветления)
← →
Игорь Шевченко © (2006-10-31 16:44) [9]Eraser © (31.10.06 16:13) [7]
> Нельзя вызывать, потому что ProcessMessages позволяет перейти
> к обработке всей очереди сообщений основного потока приложения,
> тем самым прервав выполнение кода в основном же потоке,
> до тех пор, пока метод ProcessMessages не выполнится.
С этого момента подробнее - каким образом ProcessMessages вызыванный из неосновного потока позволяет перейти к обработке всей очереди сообщений основного потока приложения.
← →
Eraser © (2006-10-31 16:47) [10]> [9] Игорь Шевченко © (31.10.06 16:44)
в том то и дело что никаким.
← →
YuRock © (2006-10-31 17:07) [11]> Ketmar c (31.10.06 16:10) [6]
> Eraser c (31.10.06 16:13) [7]
> Сергей М. c (31.10.06 16:17) [8]
Пасиба, олбанский выучил!
> dmirror (31.10.06 14:08)
Поменьше слушай голословные советы умников на форумах, побольше - читай хелп и смотри исходники.
TApplication.ProcessMessages вполне допустимо для выкрутки сообщений любого потока. Ведь это простой цикл PeekMessage. Единственное, с чем может случиться заморочка - это со свойством OnMessage у TApplication. Если оно присвоено - то будет вызываться из того потока, откуда вызвано ProcessMessages. И тут уже все зависит от того, что за код там написан. Если этого свойства нет - проблем быть не может.
Другой вопрос - зачем вызывать ProcessMessages? Оно удобно для того, чтобы выкрутить накопившуюся очередь. Принудительно.
Но не предназначено для ожидания и выкрутки сообщений, тут надо использовать цикл GetMessage.
Ниже пример с использованием Application.ProcessMessages в другом потоке. Все работает великолепно - только
неправильно логически - "оно" для другого надо. И из-за этого 100% проца жрется. Да и далеко не все сообщения "оно" обрабатывает.
Так что если этот цикл закомментить и раскомментить следующий - будет намного лучше.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TTestThread = class( TThread )
protected
procedure Execute; override;
end;
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
FTread: TTestThread;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function TestThreadWndProc( hWindow: HWND; msg: Cardinal; wParam: WPARAM; lParam: LPARAM ): Integer; stdcall;
begin
Result := DefWindowProc( hWindow, msg, wParam, lParam );
end;
procedure TTestThread.Execute;
var
hWindow: HWND;
Msg: TMSG;
begin
hWindow := CreateWindow( "___TestThreadWndClass", "Îêíî èç äðóãîãî ïîòîêà ( Îáðàáàòûâàåòñ&# 255; Application.ProcessMessages )", WS_VISIBLE or WS_SIZEBOX or WS_SYSMENU or WS_MINIMIZEBOX or WS_MAXIMIZEBOX, 100, 100, 600, 200, 0, 0, hInstance, nil );
while not Terminated do
Application.ProcessMessages;
{while not Terminated and GetMessage( Msg, 0, 0, 0 ) do begin
TranslateMessage( Msg );
DispatchMessage( Msg );
end;}
DestroyWindow( hWindow );
end;
procedure TForm1.FormCreate(Sender: TObject);
var
wc: WNDCLASS;
begin
FillChar( wc, sizeof( WNDCLASS ), 0 );
wc.lpfnWndProc := @TestThreadWndProc;
wc.hInstance := hInstance;
wc.hCursor := LoadCursor( 0, IDC_ARROW );
wc.lpszClassName := "___TestThreadWndClass";
wc.hbrBackground := CreateSolidBrush( GetSysColor( COLOR_BTNFACE ) );
Windows.RegisterClass( wc );
FTread := TTestThread.Create( True );
with FTread do begin
FreeOnTerminate := True;
Resume;
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FTread.Terminate;
end;
end.
← →
Eraser © (2006-10-31 17:17) [12]> [11] YuRock © (31.10.06 17:07)
> Пасиба, олбанский выучил!
учи еще.
только потом не удивляйся, что приложение будет "вываливаться" с AV в самых неожиданных местах.
> Да и далеко не все сообщения "оно" обрабатывает.
это с каких пор?
← →
YuRock © (2006-10-31 17:21) [13]> Eraser © (31.10.06 17:17) [12]
1. Йа пастаянна учу, пасиба исчо рас! Да, приложения, написанные мной, работают месяцами, пока винда не сдохнет.
2. С тех пор, как борланд так реализовал этот метод. Как минимум с D6 - более старых версий у меня нет под рукой.
← →
Игорь Шевченко © (2006-10-31 17:22) [14]Eraser © (31.10.06 16:47) [10]
> Нельзя вызывать, потому что ProcessMessages позволяет перейти
> к обработке всей очереди сообщений основного потока приложения,
> тем самым прервав выполнение кода в основном же потоке,
> до тех пор, пока метод ProcessMessages не выполнится.
> Если вызвать ProcessMessages из доп. потока, то программа
> или этот поток, в лучшем случае, скорее всего подвиснут.
>
> в том то и дело что никаким.
Вот две твоих цитаты. Ты их связать можешь ? А то у меня не получается.
← →
@!!ex © (2006-10-31 17:46) [15]А я почемуто всегда думал, что ProcessMessages нужно для того чтобы прервать текущее действие основного потока и обработать мессаги....
Вопрос: зачем из стороннего потока вызывать обработку сообщений главного потока?
Ответ: Чтобы напороться на AV.
← →
YuRock © (2006-10-31 17:48) [16]
> @!!ex © (31.10.06 17:46) [15]
> Вопрос: зачем из стороннего потока
> вызывать обработку сообщений главного потока?Ответ: Чтобы
> напороться на AV.
:))))))))))))))))))))))))))))))))))))))))))))))
← →
Eraser © (2006-10-31 17:57) [17]> [14] Игорь Шевченко © (31.10.06 17:22)
криво мысль изложил ) согласен.
надо было уточнить, что вызывать ProcessMessages следует из осн. потока.
> зачем из стороннего потока вызывать обработку сообщений
> главного потока?
именно это сделать нельзя. можно только если вызов обернуть в Synchronize.
← →
YuRock © (2006-10-31 18:00) [18]Я извиняюсь перед админами форума, просто нервы - ни к черту...
Через пару часов на стадион идти - Шахтер-Валенсия - и меня колбаси не по детски... Делать ничего не могу.
Орешник уже перечитал полностью. Оценил :)
Но мало. А, как оказалось, обсуждения обычных вопросов, споры и советы специалистов тут не хуже орехов :)
Так что еще раз прошу прощения и понимания. Кстати, надеюсь, какую-то пользу автору темы, к-рый задавал вопрос, я все же принес. Так что это смягчающее обстоятельство ;)
← →
Игорь Шевченко © (2006-10-31 18:09) [19]Eraser © (31.10.06 17:57) [17]
> надо было уточнить, что вызывать ProcessMessages следует
> из осн. потока.
Почему ?
← →
Eraser © (2006-10-31 18:13) [20]> [19] Игорь Шевченко © (31.10.06 18:09)
потому что borland не рекомендует вызывать методы VCL объектов из доп. потока.
← →
YuRock © (2006-10-31 18:14) [21]> Игорь Шевченко © (31.10.06 18:09) [19]
> Почему ?
Я уже задавал этот вопрос - [3].
Поступило около 15 ответов - неужели Вам не достаточно? :)
← →
@!!ex © (2006-10-31 18:16) [22]
> 1. Йа пастаянна учу, пасиба исчо рас! Да, приложения, написанные
> мной, работают месяцами, пока винда не сдохнет.
Винда дохнет из-за ваших приложений? ;)
> Игорь Шевченко © (31.10.06 18:09) [19]
Теоретически может привести к AB в ОЧЕНЬ редких случаях как уже было сказано в > Сергей М. © (31.10.06 16:17) [8] .
Мьютекс на FTerminate...
ТОка это всего лишь один из вариантов, которые могут привести к AV.
← →
Игорь Шевченко © (2006-10-31 18:21) [23]Eraser © (31.10.06 18:13) [20]
> потому что borland не рекомендует вызывать методы VCL объектов
> из доп. потока.
Все методы всех объектов ?
← →
Eraser © (2006-10-31 18:22) [24]> [21] YuRock © (31.10.06 18:14)
вот код метода ProcessMessage, который вызывается в цикле из ProcessMessages.function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
var
Unicode: Boolean;
Handled: Boolean;
MsgExists: Boolean;
begin
Result := False;
if PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE) then
begin
Unicode := (Msg.hwnd <> 0) and IsWindowUnicode(Msg.hwnd);
if Unicode then
MsgExists := PeekMessageW(Msg, 0, 0, 0, PM_REMOVE)
else
MsgExists := PeekMessage(Msg, 0, 0, 0, PM_REMOVE);
if not MsgExists then Exit;
Result := True;
if Msg.Message <> WM_QUIT then
begin
Handled := False;
if Assigned(FOnMessage) then FOnMessage(Msg, Handled); // может привести к серьезным проблемам,
// если этот обработчик расчитан для работы в осн. потоке.
if not IsPreProcessMessage(Msg) and not IsHintMsg(Msg) and // есть подозрение, что эти методы тоже не потоко-безопасны.
not Handled and not IsMDIMsg(Msg) and // тут вообще код лезет к объекту TScreen...
not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
begin
TranslateMessage(Msg);
if Unicode then
DispatchMessageW(Msg)
else
DispatchMessage(Msg);
end;
end
else
FTerminate := True; // про это сказано в [8].
end;
end;
← →
Eraser © (2006-10-31 18:25) [25]> [23] Игорь Шевченко © (31.10.06 18:21)
не всех конечно, но всех визуальных объектов. не визуальные, чаще всего (но не всегда) можно использовать не только в гл. потоке, но и в доп., но желательно только в том, где данный объект и был создан.
← →
YuRock © (2006-10-31 18:37) [26]> if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
> // может привести к серьезным проблемам,
> // если этот обработчик расчитан для работы в осн. потоке.
А может и не привести. Все зависит от того, что за код программист написал в OnMessage. И вообще - написал ли. Я этот момент упомянул в [11].
> // есть подозрение, что эти методы тоже не потоко-безопасны.
Они вполне безопасны. В них используются только элементарные функции WinApi - и нечего более.
> FTerminate := True; // про это сказано в [8].
Ну и что там сказано про это? Читаем: "поле TApplication.FTerminate не защищено крит.секцией. И при этом нет никаких гарантий, что потоку не послано WM_QUIT."
Что из этого? Ну послано - отлично! Присвоется эта переменная - так она и должна была присвоиться. НИЧЕГО страшного в этом нет.
← →
Eraser © (2006-10-31 18:45) [27]> [26] YuRock © (31.10.06 18:37)
> Они вполне безопасны. В них используются только элементарные
> функции WinApi - и нечего более.
уверен?
CancelHint к примеру? или ObjectFromHWnd? а в IsMDIMsg прямо вся состоит из вызова API? )
← →
Eraser © (2006-10-31 18:52) [28]> [26] YuRock © (31.10.06 18:37)
> Что из этого? Ну послано - отлично! Присвоется эта переменная
> - так она и должна была присвоиться. НИЧЕГО страшного в
> этом нет.
таки слона то мы все и не приметели )) как только доп. потоку будет послано WM_QUIT - приложение завершиться )
← →
YuRock © (2006-10-31 19:02) [29]
> уверен?CancelHint к примеру? или ObjectFromHWnd? а в IsMDIMsg
> прямо вся состоит из вызова API? )
Уверен на 100%. К этой строке выполнение может дойти только тогда, когда в потоке созданы VCL-ные хинты. А в дополнительных потоках их создать и работать с ними если не невозможно, то довольно сложно, как и с любыми VCL-объектами.
А IsMDIMsg, да, состоит вся из вызова API.
> таки слона то мы все и не приметели )) как только доп. потоку
> будет послано WM_QUIT - приложение завершиться )
Да, должно завершиться. Ну и? А в чем еще смысл посылки WM_QUIT? Обычно для этого как раз...
P.S. Все, спасибо всем за положительные эмоции - пора выдвигаться на стадио :)
← →
Eraser © (2006-10-31 19:17) [30]> [29] YuRock © (31.10.06 19:02)
> А IsMDIMsg, да, состоит вся из вызова API.
и чтения свойств визуальных VCL объектов.
при завершении приложения, если доп. поток еще будет ативен, в этом месте AV обязательно вылетит.function TApplication.IsMDIMsg(var Msg: TMsg): Boolean;
begin
Result := False;
if (MainForm <> nil) and (MainForm.FormStyle = fsMDIForm) and
(Screen.ActiveForm <> nil) and (Screen.ActiveForm.FormStyle = fsMDIChild) then
Result := TranslateMDISysAccel(MainForm.ClientHandle, Msg);
end;
> Да, должно завершиться.
это еще с какого перепугу? обычно (не заню как там у вас) WM_QUIT служит для завершения потока, а т.к. поток не основоной, зачем закрывать программу, да еще и через задний проход?
не слишкол ли много "если" надо учесть, чтобы код работал как надо?
по-моемуwhile not Terminated and GetMessage(Msg, 0, 0, 0) do begin
TranslateMessage( Msg );
DispatchMessage( Msg );
end;
гораздо проще и безопаснее.
← →
@!!ex © (2006-10-31 20:46) [31]
> YuRock
ощущени, что вы с потоками не работали....
В курсе, что будет если к одной переменной одновременно обратяться из двух разных потоков?
Семафоры и мьютексы не просто так придумали.
← →
Дмитрий Белькевич © (2006-11-01 02:44) [32]Господа, вам в жизни проблем мало, что бы еще и на эти грабли наступать - в appllication.processmessage может случится многое - нажатия на кнопки, перерисовка итд. И коматоз обеспечен.
← →
Игорь Шевченко © (2006-11-01 10:53) [33]Eraser © (31.10.06 19:17) [30]
> if (MainForm <> nil) and (MainForm.FormStyle = fsMDIForm)
property FormStyle: TFormStyle read FFormStyle
property ActiveForm: TForm read FActiveForm;
И чего ?
> при завершении приложения, если доп. поток еще будет ативен,
> в этом месте AV обязательно вылетит.
Пример не затруднит ?
← →
dmirror (2006-11-01 11:58) [34]ProcessMessagess запускается в основной программе а не в потоке, в потоке обслуживается генераторно-осцилографическая часть. А ProcessMessagess нужен для отслеживания событий системы позиционирования, просто без него не могу получить сигнал готовности.
Код слующий
procedure TForm1.ScanStartClick(Sender: TObject);
var
i,j : integer;
sx,sy,vx,vy : string;
uclen, k,h : integer;
temp : real;
begin
vx := Edit16.Text;
vy := Edit17.Text;
sx := Edit18.Text;
sy := Edit19.Text;
Stringcounter :=1;
IsFastScan:=true;
cRecBufSizeMaxF:=trunc(cSamplPS*StrToInt(sx)/StrToInt(vx));
cRecBufSizeMaxFBin:=(cRecBufSizeMaxF - (cRecBufSizeMaxF mod 2))*2;
for i:=1 to StrToInt(numlines.Text) do
begin
sleep(200);
isReady :=false;
cport.WriteStr("@0A 0,5000,"+sy+","+vy+#13#10);
start;
j:=0;
repeat
inc(j);
application.ProcessMessages();
until IsReady;{ or (j>=15);
if (j>=15) then begin
ShowMessage("Каретка не дошла до конца");
end; }
sleep(200);
isReady :=false;
Cport.WriteStr("@0A 0,5000,"+"-"+sy+","+vy+#13#10);
repeat
application.ProcessMessages();
until isReady = true;
sleep(200);
isReady :=false;
Cport.WriteStr("@0A"+sx+","+vx+",0,5000"+#13#10);
repeat
stringcounter:=Stringcounter+1;
application.ProcessMessages();
until isReady;
end;
IsFastScan:=false;
end;
А ларчик открывался достаточно просто - нужно было убить библиотеку svcmgr. После чего ProcessMessages заработал. А вот первопричина не понятна, в чистом приложении без потоков даже с svcmgr код работал
Всем спасибо!
← →
dmirror (2006-11-01 11:58) [35]ProcessMessagess запускается в основной программе а не в потоке, в потоке обслуживается генераторно-осцилографическая часть. А ProcessMessagess нужен для отслеживания событий системы позиционирования, просто без него не могу получить сигнал готовности.
Код слующий
procedure TForm1.ScanStartClick(Sender: TObject);
var
i,j : integer;
sx,sy,vx,vy : string;
uclen, k,h : integer;
temp : real;
begin
vx := Edit16.Text;
vy := Edit17.Text;
sx := Edit18.Text;
sy := Edit19.Text;
Stringcounter :=1;
IsFastScan:=true;
cRecBufSizeMaxF:=trunc(cSamplPS*StrToInt(sx)/StrToInt(vx));
cRecBufSizeMaxFBin:=(cRecBufSizeMaxF - (cRecBufSizeMaxF mod 2))*2;
for i:=1 to StrToInt(numlines.Text) do
begin
sleep(200);
isReady :=false;
cport.WriteStr("@0A 0,5000,"+sy+","+vy+#13#10);
start;
j:=0;
repeat
inc(j);
application.ProcessMessages();
until IsReady;{ or (j>=15);
if (j>=15) then begin
ShowMessage("Каретка не дошла до конца");
end; }
sleep(200);
isReady :=false;
Cport.WriteStr("@0A 0,5000,"+"-"+sy+","+vy+#13#10);
repeat
application.ProcessMessages();
until isReady = true;
sleep(200);
isReady :=false;
Cport.WriteStr("@0A"+sx+","+vx+",0,5000"+#13#10);
repeat
stringcounter:=Stringcounter+1;
application.ProcessMessages();
until isReady;
end;
IsFastScan:=false;
end;
А ларчик открывался достаточно просто - нужно было убить библиотеку svcmgr. После чего ProcessMessages заработал. А вот первопричина не понятна, в чистом приложении без потоков даже с svcmgr код работал
Всем спасибо!
← →
Сергей М. © (2006-11-01 13:30) [36]
> нужно было убить библиотеку svcmgr
А как она у тебя оказалась в проекте обычного GUI-приложения ?
← →
YuRock © (2006-11-01 15:17) [37]
> ощущени, что вы с потоками не работали....В курсе, что будет
> если к одной переменной одновременно обратяться из двух
> разных потоков?Семафоры и мьютексы не просто так придумали.
>
Да, знаю. В худшем случае - логические ошибки. Которые, конечно, могут повлечь за собой все, что угодно. А могут и не повлечь, как в случае с безобидным сравнение двух чисел:if (MainForm <> nil) and (MainForm.FormStyle = fsMDIForm)
← →
Eraser © (2006-11-01 15:20) [38]> [33] Игорь Шевченко © (01.11.06 10:53)
мда.. насчет AV в (MainForm <> nil) and (MainForm.FormStyle = fsMDIForm) эт я погорячился, не учел тот факт, что форма не уничтожается, когда заканчивается Run. Но сути дела это не меняет. Я б не стал использовать методы TApplication для обработки сообщений в доп. потоке.
← →
Anatoly Podgoretsky © (2006-11-01 15:23) [39]> Eraser (01.11.2006 15:20:38) [38]
> (MainForm <> nil) and (MainForm.FormStyle = fsMDIForm)
С потоками, я бы не назвал это код безобидным, легко получить как минимум AV
Это не атомарная операция.
← →
Eraser © (2006-11-01 15:24) [40]> [37] YuRock © (01.11.06 15:17)
> (MainForm <> nil) and (MainForm.FormStyle = fsMDIForm)
кстати подобных конструкций тоже стараюсь избегать.. в отличие от борланада ) хотя они если и поменяют работу компилятора - первые об этом узнают и перепишут код, а вот мне искать внезапно-появившиеся ошибки, при переходе на новую версию компилятора, в проекте на несколько десятков тысяч строк не хочется.
← →
Eraser © (2006-11-01 15:25) [41]> [39] Anatoly Podgoretsky © (01.11.06 15:23)
ну записи то там нет.
← →
Anatoly Podgoretsky © (2006-11-01 15:45) [42]> Eraser (01.11.2006 15:24:40) [40]
Да код не безобидный даже и без потоков, легко получить не то что задумал.
Но это уже много раз разжевывалось.
← →
Anatoly Podgoretsky © (2006-11-01 15:47) [43]> Eraser (01.11.2006 15:25:41) [41]
За то есть обращение к непринадлежащей тебе памяти. Между первой и второй
перерывчик не большой, во время которого второй поток уже уничтожил объект -
тут нужна критическая секция.
← →
YuRock © (2006-11-01 16:08) [44]
> Anatoly Podgoretsky © (01.11.06 15:47) [43]
> За то есть обращение
> к непринадлежащей тебе памяти. Между первой и второйперерывчик
> не большой, во время которого второй поток уже уничтожил
> объект -тут нужна критическая секция.
Блин, а голова программеру на что? Естественно, что пользоваться средствами, предоставленными Борландом, Майкрософтом и т.д. надо с умом! В этом случае, например, если используешь Application.ProcessMessages для выкрутки сообщений другого потока, надо знать, что желательно поток-то этот закрыть вообще нафиг, перед тем, как MainForm уничтожится (если она была вообще, конечно).
> Eraser © (01.11.06 15:24) [40]
> (MainForm.FormStyle = fsMDIForm)кстати подобных конструкций
> тоже стараюсь избегать.. в отличие от борланада ) хотя они
> если и поменяют работу компилятора - первые об этом узнают
> и перепишут код, а вот мне искать внезапно-появившиеся ошибки,
> при переходе на новую версию компилятора, в проекте на
> несколько десятков тысяч строк не хочется.
А с этим кодом что плохого? И при чем тут компилятор?
← →
Anatoly Podgoretsky © (2006-11-01 16:21) [45]> YuRock (01.11.2006 16:08:44) [44]
> а голова программеру на что
А ты много такого видел, откуда тогда берутся AV?
← →
YuRock © (2006-11-01 16:26) [46]
> А ты много такого видел, откуда тогда берутся AV?
Нет, немного. Я видел только один случай, откуда берутся AV: когда обращаются к адресу памяти, доступа к которому нет.
← →
Anatoly Podgoretsky © (2006-11-01 16:51) [47]> YuRock (01.11.2006 16:26:46) [46]
Например между первой и второй перерывчик небольшой.
← →
@!!ex © (2006-11-01 16:58) [48]
> YuRock © (01.11.06 16:26) [46]
Собственно никто не обещает, что при проверке второй части условия форма все еще будет не Nil. :))
← →
Anatoly Podgoretsky © (2006-11-01 17:04) [49]> @!!ex (01.11.2006 16:58:48) [48]
Это первая проблема, а вторая никто не гарантирую, что не будут вычисляться
обе части выражения, первая безопасная, а по второй имеется счастье получить
AV по полной программе. Зависит от настроек компилятора.
Помню как кто то очень громко ругался на форумах :-)
← →
Игорь Шевченко © (2006-11-01 17:06) [50]@!!ex © (01.11.06 16:58) [48]
> Собственно никто не обещает, что при проверке второй части
> условия форма все еще будет не Nil. :))
А собственно, посмотреть, при каких условиях она станет nil при проверке второго условия ?
← →
@!!ex © (2006-11-01 17:13) [51]
> Игорь Шевченко © (01.11.06 17:06) [50]
Если поток на некоторое время зависинит(ОС не гарантирует что всем потокам выделяется абсолютно одинаковое количество процессорного времени) и за это время форма будет уничтожена.
← →
Eraser © (2006-11-01 17:20) [52]> [44] YuRock © (01.11.06 16:08)
> Блин, а голова программеру на что? Естественно, что пользоваться
> средствами, предоставленными Борландом, Майкрософтом и т.д.
> надо с умом!
за такое "с умом" с работы попереть могут. я бы призадумался о компетенции такого работника.
учти, что даже если тебе полностью понятно, как работает этот код в текущей версии VCL, человек, который возможно в будущем будет заниматься поддержкой/развитием данного кода может быть не в курсе тонкостей.
← →
Игорь Шевченко © (2006-11-01 17:30) [53]@!!ex © (01.11.06 17:13) [51]
Который из потоков ? :)
← →
@!!ex © (2006-11-01 17:46) [54]Зависнет поток в котором выполняется
(MainForm <> nil) and (MainForm.FormStyle = fsMDIForm)
И за это время выполнится удаление MainForm
← →
Игорь Шевченко © (2006-11-01 17:49) [55]@!!ex © (01.11.06 17:46) [54]
Особенно интересен момент удаления MainForm у Application. Я к чему говорю - на свете есть много моментов получения AV, просто у ряда из них частота возникновения невелика...
← →
@!!ex © (2006-11-01 17:51) [56]Это придирка к примеру, не я его придумал. :)
ДА. Согласен. В таких слуаях AV ОЧЕНЬ редко, но всеже имеет место быть.
И это не есть гуд.
Такие AV хуже всего ловятся.
А когда прога падает раз в месяц и никто не может понять почему.... Программисты получают втыки.
← →
YuRock © (2006-11-01 17:59) [57]
> А когда прога падает раз в месяц и никто не может понять
> почему....
Мои проги не падают - я же говорил :)
Без перезапуска работают месяцами, пока винда не "попросит" перезагрузки из-за того, что юзер в какую-нибудь игру поиграл или еще что...
← →
Игорь Шевченко © (2006-11-01 18:01) [58]@!!ex © (01.11.06 17:51) [56]
К сожалению, падающие раз в месяц проги обычно падают по иным причинам, нежели ProcessMessages, вызванный из другого потока.
Кроме того, программы обычно тестируют, как ни странно, выявляя массу ошибок и прочего непредсказуемого поведения.
Я бы не стал рекомендовать использование Application.ProcessMessages из другого потока только по одной причине - это неочевидный код. А любой неочевидный код должен найти свое законное место в корзине.
Других причин (вроде запрета вызова метода VCL-объекта из другого потока, ловля блох в последовательных проверках существования объекта и его теоретического уничтожения между проверками) я не вижу.
← →
YuRock © (2006-11-01 18:06) [59]
> Eraser © (01.11.06 17:20) [52]
> за такое "с умом" с работы попереть могут. я бы призадумался о компетенции такого работника.
Ок, я задумаюсь над своей компетенцией :)
> учти, что даже если тебе полностью понятно,
> как работает этот код в текущей версии VCL,
Ну, переходить на версию деолфей больше 6 я не собираюсь, и все мысли подчиненных на эту тему обрезаю накорню. Приводя примеры глюков компилятора D7 и выше, на которые я натыкался. Да, обойти их можно, но перелопачивать 70 мегабайт кода никто не будет.
> человек, который
> возможно в будущем будет заниматься поддержкой/развитием
> данного кода может быть не в курсе тонкостей.
А вот за такое с работы попереть могут :)
← →
YuRock © (2006-11-01 18:14) [60]> @!!ex
> Eraser
Да, и почему вы решили, что я - за использование Application.ProcessMessages в других потоках? Это удобно, лишь если есть желание компилить проект на Кайликсе. Да и то - сомнительно.
Просто прозвучало утверждение: "Не вздумай!!!..."
А когда я знаю, что это точно можно, а мне говорят, что точно нельзя, я задал вполне логичный вопрос: "Почему?"
И, естественно, ответ типа "Пока поверь мне на слово, а потом подростешь - поумнеешь" меня не полностью удовлетворил :)
← →
Eraser © (2006-11-01 18:19) [61]> [59] YuRock © (01.11.06 18:06)
> Приводя примеры глюков компилятора D7 и выше, на которые
> я натыкался.
imho 7 - самая стабильная после 3 версия, хотя пользуюсь 10 )
> Ну, переходить на версию деолфей больше 6 я не собираюсь
если кода много переписывать прийдется, тоже не вижу смысла, лучше сразу на C# %-)
> > человек, который
> > возможно в будущем будет заниматься поддержкой/развитием
>
> > данного кода может быть не в курсе тонкостей.
>
>
> А вот за такое с работы попереть могут :)
могут! если он не найдет ошибку, а если найдет, то сразу же перепишет как надо, при этом матеря аффтора того кода )
> Других причин (вроде запрета вызова метода VCL-объекта из
> другого потока, ловля блох в последовательных проверках
> существования объекта и его теоретического уничтожения между
> проверками) я не вижу.
а я не вижу гарантии, что в следующей версии VCL, туда не запуздырят какую-нибудь инструкцию, из-за которой данный код будет "падать". Ведь было же такое и не раз, не мне вам рассказывать.
← →
Leonid Troyanovsky © (2006-11-01 19:21) [62]
> YuRock © (01.11.06 18:14) [60]
> потом подростешь - поумнеешь" меня не полностью удовлетворил
Да, это так оно и есть. Подрастают, но не умнеют.
Отсюда и произрастает неудовлетворенность.
--
Regards, LVT.
← →
@!!ex © (2006-11-01 20:36) [63]Помоему уже раз 10 на примерх показали, почему не стоит обращаться к незащищенным переменным и методам из разных потоков.
← →
Leonid Troyanovsky © (2006-11-01 21:00) [64]
> @!!ex © (01.11.06 20:36) [63]
> Помоему уже раз 10 на примерх показали,
Маловато будет.
--
Regards, LVT.
← →
YuRock © (2006-11-02 15:11) [65]
> @!!ex © (01.11.06 20:36) [63]
> Помоему уже раз 10 на примерх показали, почему не стоит
> обращаться к незащищенным переменным и методам из разных
> потоков.
Пока что был только 1 пример - мой, со 100% работающим кодом с ProcessMessages из другого потока.
Остальное - только рассуждения и предположения, не более того.
Если ошибаюсь, или я слепой - напиши номер поста с этими примерами. Желательно - 10-ти примеров. Касающихся сути вопроса, естественно. А почему так делать иногда нельзя - думаю, что знаю это не хуже тебя.
Подчеркиваю - иногда!
Ты ведь пользуешься переменной IsMultiThread в резных потоках, и не засовываешь обращения в CS? Или DecimalSeparator? И таких примеров - действительно миллион. Так зачем чушь нести? И какое это все вообще имеет отношение к теме вопроса?
← →
Сергей М. © (2006-11-02 15:29) [66]
> YuRock © (02.11.06 15:11) [65]
Если ты, дружок ситный, завел всю эту безапелляционную трындельню, то ты, дружок ситный, должен при этом понимать, что объект Application, чей метод ProcessMessages вызывается в потоке X, должен быть создан не иначе как в контексте потока Х.
В противном случает цена твоей трындельне - три копейки в базарный день)
← →
YuRock © (2006-11-02 15:37) [67]
> Сергей М. © (02.11.06 15:29) [66]
> > YuRock © (02.11.06 15:11) [65]Если ты, дружок ситный,
> завел всю эту безапелляционную трындельню, то ты, дружок
> ситный, должен при этом понимать, что объект Application,
> чей метод ProcessMessages вызывается в потоке X, должен
> быть создан не иначе как в контексте потока Х.В противном
> случает цена твоей трындельне - три копейки в базарный день)
А, что, по твоему есть разница, в каком потоке выделять память? :)))))))))))))
← →
Сергей М. © (2006-11-02 15:41) [68]
> YuRock © (02.11.06 15:37) [67]
Причем здесь выделение, дружок ?
Речь идет об обращении к одному и тому же (уже существующему !) объекту TApplication в контексте более чем одного потока процесса
← →
YuRock © (2006-11-02 15:48) [69]
> Сергей М. © (02.11.06 15:41) [68]
> Речь идет об обращении к одному и тому же (уже
> существующему !) объекту TApplication в контексте более
> чем одного потока процесса
Т.е. если объект создан в потоке X, то в потоке Y его использовать нельзя. Так?
← →
Eraser © (2006-11-02 16:13) [70]> [69] YuRock © (02.11.06 15:48)
его нельзя использовать в обоих потоках одновременно.
← →
Сергей М. © (2006-11-02 16:13) [71]
> если объект создан в потоке X, то в потоке Y его использовать
> нельзя. Так?
Репу почесав - можно.
И оную же почесав - нельзя.
Репа программеру дана не только для пожирания чего-то там)
← →
YuRock © (2006-11-02 16:30) [72]
> Eraser © (02.11.06 16:13) [70]
> его нельзя использовать в обоих потоках одновременно.
> Сергей М. © (02.11.06 16:13) [71]
> Репу почесав - можно.И оную же почесав - нельзя.
Ребята, зачем вы чушь несете? Вас же вообще ничего незнающие люди читают и верят!!!
Вы пользуетесь компонентами типа Indy, IBX... Да просто классом TThread? Если да - то вы ОБЯЗАТЕЛЬНО ОДНОВРЕМЕННО используете один объект в разных потоках!
← →
BiN © (2006-11-02 16:36) [73]Application.ProcessMessages в дополнительном потоке - всё равно что трусы на голове - носить можно, но глупо и чревато менингитом с летальным исходом.
← →
Сергей М. © (2006-11-02 16:49) [74]
> YuRock © (02.11.06 16:30) [72]
> Ребята, зачем вы чушь несете?
Затем чтобы никому не было повадно использовать сабж в своих многопоточных разработках при использовании VCL.
Get/Peek/WaitMessage упразднены уже, а ?
← →
Eraser © (2006-11-02 16:49) [75]> [72] YuRock © (02.11.06 16:30)
> Если да - то вы ОБЯЗАТЕЛЬНО ОДНОВРЕМЕННО используете один
> объект в разных потоках!
не используем.
← →
YuRock © (2006-11-02 16:59) [76]
> не используем.
Мда? А никогда не приходилось в TThread.Execute делать такой цикл:
while not Terminated do begin
//...
end;
а при закрытии приложения, чтобы корректно завершить работу этого потока вызвать, например, Thead1.Terminate или Thead1.Free, который тоже вызовет Terminate?
Если приходилось (а такого не могло не случиться :) ), то да, используете... Переменную класса TThread.FTerminated присваиваете в одном потоке, а используете - в другом... Безо всяких CS. И это - общепринятый метод - когда можно - использовать такое. Одновременно :)
← →
BiN © (2006-11-02 17:04) [77]
> YuRock © (02.11.06 16:59) [76]
>
> Переменную класса TThread.FTerminated
> присваиваете в одном потоке, а используете - в другом...
> Безо всяких CS. И это - общепринятый метод - когда можно
> - использовать такое. Одновременно :)
>
Все дело в SizeOf(FTerminated).
скучно...
← →
Сергей М. © (2006-11-02 17:05) [78]
> YuRock © (02.11.06 16:59) [76]
Байка о бузине и дядьке.
Диагноз - "В сад" (С)
← →
YuRock © (2006-11-02 17:09) [79]
> Все дело в SizeOf(FTerminated).
Не только. TThread.FSynchronizeException еще очень большое значение имеет в этом контексте...
← →
BiN © (2006-11-02 17:15) [80]
> YuRock © (02.11.06 17:09) [79]
>
>
> Не только. TThread.FSynchronizeException еще очень большое
> значение имеет в этом контексте...
И какое же значение?
← →
Сергей М. © (2006-11-02 17:19) [81]
> YuRock © (02.11.06 17:09) [79]
Не надо тут уже лепить про атомарность операций ввода/вывода рпо отношению к операндам размером в 1 байт.
Сто раз обсуждалось.
Облажаешься - не отмоешься.
← →
YuRock © (2006-11-02 17:34) [82]
> И какое же значение?
Не меньшее, чем SizeOf(Boolean)
> Не надо тут уже лепить про атомарность операций ввода/вывода
> рпо отношению к операндам размером в 1 байт.
Вот метод TThread.Destroy, который вызывается в другом потоке:destructor TThread.Destroy;
begin
if (FThreadID <> 0) and not FFinished then
begin
Terminate;
...
end;
Думаешь, размер FThreadID 1 байт?
> Облажаешься - не отмоешься.
Это не всегда и не по всем заметно... почему-то...
← →
Eraser © (2006-11-02 19:28) [83]> [76] YuRock © (02.11.06 16:59)
где одновременное использование?
> [82] YuRock © (02.11.06 17:34)
> Думаешь, размер FThreadID 1 байт?
метод Destroy выполняется в основном потоке, FThreadID устанавливается тоже в основном потоке. Свойство ThreadID только для чтения, так что никаких конфликтов быть не должно.
Да и, мягко говоря, не удачный ты класс для примера выбрал.. TThread специально спроектирован для работы с доп. потоками, поэтому тут узких мест быть не должно.
← →
Eraser © (2006-11-02 19:39) [84]> метод Destroy выполняется в основном потоке
поправочка OnTerminate, т.е. откуда возможен доступ к полям объекта.
← →
YuRock © (2006-11-02 19:44) [85]
> Eraser © (02.11.06 19:28) [83]
Ну так я его именно потому и выбрал :)
А свойство ThreadID, значит, нельзя использовать в коде потока?
Ладно с этим методом. Просто прозвучало утверждение: "Обращения ко всем переменные, использующиеся в разных потоках, обязательно надо синхронизировать, иначе буду AV, зависания и т.д.".
Ну хорошо. Синхронизируем. Перед использованием, скажем, некой переменной пишем:
EnterCriticalSection( CS );
//...
И получаем использование переменной CS (как минимум чтение) в разных потоках.
Так вот, меня интересует простой вопрос - зачем вводить в заблуждение читателей форума?
← →
YuRock © (2006-11-02 19:45) [86]
> Eraser © (02.11.06 19:39) [84]
> > метод Destroy выполняется в основном потокепоправочка
> OnTerminate, т.е. откуда возможен доступ к полям объекта.
>
Метод Destroy может выполняться в любом потоке.
← →
Eraser © (2006-11-02 19:50) [87]> [85] YuRock © (02.11.06 19:44)
пока что в заблуждение всех вводишь ты.
> Обращения ко всем переменные, использующиеся в разных потоках,
> обязательно надо синхронизировать, иначе буду AV, зависания
> и т.д.
ты с этим не соглсен?
из всех правил есть исключения, но это не значит, что нужно игнорировать правила.
← →
Eraser © (2006-11-02 19:51) [88]> [86] YuRock © (02.11.06 19:45)
согласен, в [84] я себя поправил.
← →
YuRock © (2006-11-02 19:58) [89]
> ты с этим не соглсен?из всех правил есть исключения, но
> это не значит, что нужно игнорировать правила.
Это не правила. Это логика программ. При чем тут исключения из правил.
> согласен, в [84] я себя поправил.
Я другое имел ввиду. Ты написал, что Destroy вызывается из основного потока, а на самом деле его можно вызывать из какого-угодно.
← →
Eraser © (2006-11-02 20:07) [90]> [89] YuRock © (02.11.06 19:58)
> Ты написал, что Destroy вызывается из основного потока
вот это я и поправил, имелось ввиду OnTerminate.
> Это логика программ
логика программ в том, что TThread спроектирован для работы в разных потоках, а TApplication - нет.
Страницы: 1 2 3 вся ветка
Форум: "WinAPI";
Текущий архив: 2007.03.11;
Скачать: [xml.tar.bz2];
Память: 0.74 MB
Время: 0.076 c