powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Шаблон класса для работы с потоком (WThread, Thread)
25 сообщений из 469, страница 2 из 19
Шаблон класса для работы с потоком (WThread, Thread)
    #38412305
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустамя бы ни в коем, НИ В КОЕМ случае
не использовал сообщения/события для обмена данными,
только для сигнализации. Тем более в шаблоне потока.
И это правильно. Шаблон-же. Нужна копия данных, с выделением памяти. Но вот

Dimonka,

кажется хочет сделать свою работу моими руками, подогнав за мой счет шаблон под конкретную задачу. :)
DimonkaМожешь тестировать :)
Напишу конкретный парсер, где процедура парсинга будет твоя. А остальное, вместе с менеджером потоков, белым/черным списком урлов и диагностическими сообщениями - мое. Недорого.
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38412314
Фотография Dimonka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman,

Получается, вместо примера использования ты показываешь мусор.
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38412316
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimonka, некрасиво брать на слабо. Идеального кода не существует, как и людей. Научись адаптировать код, если программист. Это лишь шаблон, который справляется с необходимым минимумом.
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38412417
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамНИ В КОЕМ случае не использовал сообщения/события для обмена данными

Майкрософт ниего против не имеет, однако: http://msdn.microsoft.com/en-us/library/windows/desktop/ms649011.aspx
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38412448
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch> Майкрософт ниего против не имеет, однако

Ну, Майкрософту и вам, с ним согласным, виднее, конечно.
Можете хоть в ногу себе стрелять, MS тоже против не будет.

P.S. Если уж чешется WM_COPYDATA, то лучше напрямую
MMF использовать (оно через них работает, AFAIK).

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38412449
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, не заметил по ссылке ничего про "не имеет против".

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38412555
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AriochМайкрософт ниего против не имеет
У МС примеры, которые я подсматривал как раз таки имеют свойство копировать данные (LocalAlloc, LocalFree) и передавать ссылку при работе с потоками.
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38412558
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нечто такое:
Код: pascal
1.
2.
3.
4.
5.
6.
            i := Length(Value)*SizeOfChar+SizeOfChar;
            buf1 := Pointer(LocalAlloc(LPTR, i));
            if (buf1 <> nil)and(FWindowHandle <> 0) then begin
                Move(PChar(Value)^, buf1^, i);
                PostMessage(FWindowHandle, WM_RECEIVE, 0, LPARAM(buf1));
            end;
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38412684
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тем не менее, никаких рекомендаций против использования WM_COPYDATA там нет, ни в общем виде ни ввиде ограничений
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38412772
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimonka, в общем, я учел твое замечание и допилил малость. Хотя все равно считаю, что твой пример - сие есть ошибка в проектировании: нужен менеджер потоков, который реагирует на занятость/свободность потоков.

Шаблон:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
unit WThread;
// модуль-шаблон для работы с доп.потоками
// позволяет "общаться" дополнительному и основному потокам посредством системной очереди сообщений
// без вызова синхронизации
// (c) wadman 2013
// допиливание и замечания приветствуются

// 1 для работы необходимо изменить/дописать метод Execute
// 2 присвоить необходимые события OnReceiveXXX - это события будут вызываться в основном потоке в порядке очереди
// 3 protected процедуры SendXXX используются в Execute, т.е. внути доп. потока и вызывают соответствующие события
//   в совновном потоке. см.п.2
// 4 для сообщения информации доп.потоку из основного используются процедуры SendToThreadXXX

interface

uses
    Classes,
    Windows,
    Messages,
    SysUtils;

type
    TWThread = class;

    // событие на получение строки из потока
    TWThreadReceiveString = procedure(Sender: TWThread; const Text: string) of object;
    // событие на получение числа из потока
    TWThreadReceiveInt = procedure(Sender: TWThread; const Int: Integer) of object;
    // событие на получение строки и числа из потока
    TWThreadReceiveStringWord = procedure(Sender: TWThread; const Text: string; const DWrd: DWord) of object;
    // событие на получение двух чисел из потока
    TWThreadReceiveIntWord = procedure(Sender: TWThread; const Int: Integer; const DWrd: DWord) of object;
    // событие на получение сообщения из потока
    TWThreadReceiveMessage = procedure(Sender: TWThread; const Msg: Cardinal; const WParam: WPARAM; const LParam: LPARAM) of object;

    TWThread = class(TThread)
    private
        FToolWindow: THandle;
        hCloseEvent: THandle;
        FOnThreadReceiveString: TWThreadReceiveString;
        FOnThreadReceiveInt: TWThreadReceiveInt;
        FOnThreadReceiveStringWord: TWThreadReceiveStringWord;
        FOnThreadReceiveIntWord: TWThreadReceiveIntWord;
        FOnThreadReceiveMessage: TWThreadReceiveMessage;
    protected
        function NewString(const Text: string): Pointer;
        function FreeString(var P: LPARAM): String;
        procedure WWindowProc(var Msg: TMessage);
        // 5 процедур отправки данных из Execute, с вызовом событий OnThreadReceiveXXX в основном потоке
        procedure SendString(const Text: string);
        procedure SendInteger(const Int: Integer);
        procedure SendStringWord(const Text: string; const Wrd: DWord);
        procedure SendIntegerWord(const Int: Integer; const Wrd: DWord);
        procedure SendMyMessage(const Msg: TMessage);

        procedure DoThreadReceiveString(const Text: string);
        procedure DoThreadReceiveInt(const Int: Integer);
        procedure DoThreadReceiveStringWord(const Text: string; const DWrd: DWord);
        procedure DoThreadReceiveIntWord(const Int: Integer; const DWrd: DWord);
        procedure DoThreadReceiveMessage(const Msg: Cardinal; const WParam: WPARAM; const LParam: LPARAM);
        procedure Execute; override; // шаблон процедуры
    public
        constructor Create(CreateSuspended: Boolean); virtual;
        destructor Destroy; override;
        // отправка любого сообщения В поток
        function SendToThreadMessage(AMsg: UInt; wParam: WPARAM; lParam: LPARAM): BOOL;
        // отправка строки В поток
        function SendToThreadString(const Text: string): boolean;
        // отправка числа и строки В поток
        function SendToThreadStringWord(const Text: string; const Wrd: DWord): boolean;
        // отправка числа В поток
        function SendToThreadInt(const Int: Integer): boolean;
        // отправка двух чисел В поток
        function SendToThreadIntWord(const Int: Integer; const Wrd: DWord): boolean;
        // остановка потока по феншую
        function StopThread: boolean;
        // события на получение данных ИЗ потока, вызываются в основном потоке
        property OnThreadReceiveString: TWThreadReceiveString read FOnThreadReceiveString write FOnThreadReceiveString;
        property OnThreadReceiveInt: TWThreadReceiveInt read FOnThreadReceiveInt write FOnThreadReceiveInt;
        property OnThreadReceiveStringWord: TWThreadReceiveStringWord read FOnThreadReceiveStringWord write FOnThreadReceiveStringWord;
        property OnThreadReceiveIntWord: TWThreadReceiveIntWord read FOnThreadReceiveIntWord write FOnThreadReceiveIntWord;
        property OnThreadReceiveMessage: TWThreadReceiveMessage read FOnThreadReceiveMessage write FOnThreadReceiveMessage;
    end;

implementation

const
    WM_BASE             = WM_USER + $100;
    WM_STRING           = WM_BASE + 1;
    WM_INT              = WM_BASE + 2;
    WM_STRING_WORD      = WM_BASE + 3;
    WM_INT_WORD         = WM_BASE + 4;
    WM_MSG              = WM_BASE + 5;

    WM_MAX              = WM_MSG;

    SizeOfChar          = SizeOf(Char);

{ TWThread }

constructor TWThread.Create(CreateSuspended: Boolean);
begin
    inherited;
    FToolWindow := AllocateHWnd(WWindowProc);
    hCloseEvent := CreateEvent(nil, true, false, nil);
end;

destructor TWThread.Destroy;
begin
    CloseHandle(hCloseEvent);
    DeallocateHWnd(FToolWindow);
    inherited;
end;

procedure TWThread.DoThreadReceiveInt(const Int: Integer);
begin
    if Assigned(FOnThreadReceiveInt) then
        FOnThreadReceiveInt(Self, Int);
end;

procedure TWThread.DoThreadReceiveIntWord(const Int: Integer; const DWrd: DWord);
begin
    if Assigned(FOnThreadReceiveIntWord) then
        FOnThreadReceiveIntWord(Self, Int, DWrd);
end;

procedure TWThread.DoThreadReceiveMessage(const Msg: Cardinal; const WParam: WPARAM; const LParam: LPARAM);
begin
    if Assigned(FOnThreadReceiveMessage) then
        FOnThreadReceiveMessage(Self, Msg, WParam, LParam);
end;

procedure TWThread.DoThreadReceiveString(const Text: string);
begin
    if Assigned(FOnThreadReceiveString) then
        FOnThreadReceiveString(Self, Text);
end;

procedure TWThread.DoThreadReceiveStringWord(const Text: string; const DWrd: DWord);
begin
    if Assigned(FOnThreadReceiveStringWord) then
        FOnThreadReceiveStringWord(Self, Text, DWrd);
end;

function TWThread.SendToThreadMessage(AMsg: UInt; wParam: WPARAM; lParam: LPARAM): BOOL;
begin
    result := PostThreadMessage(ThreadID, AMsg, wParam, lParam);
end;

function TWThread.SendToThreadString(const Text: string): boolean;
var buf: Pointer;
begin
    buf := NewString(Text);
    result := PostThreadMessage(ThreadID, WM_STRING, 0, LPARAM(buf));
end;

function TWThread.SendToThreadStringWord(const Text: string; const Wrd: DWord): boolean;
var buf: Pointer;
begin
    buf := NewString(Text);
    result := PostThreadMessage(ThreadID, WM_STRING_WORD, Wrd, LPARAM(buf));
end;

function TWThread.SendToThreadInt(const Int: Integer): boolean;
begin
    result := PostThreadMessage(ThreadID, WM_INT, 0, Int);
end;

function TWThread.SendToThreadIntWord(const Int: Integer; const Wrd: DWord): boolean;
begin
    result := PostThreadMessage(ThreadID, WM_INT_WORD, Wrd, Int);
end;

procedure TWThread.Execute;
var
    HandlesToWaitFor: array [0 .. 0] of THandle;
    dwHandleSignaled: DWORD;
    msg: TMsg;
    str: string;

    MSWait: Cardinal;
Label
    EndOfThread;
begin
    // следующая строка должна быть всегда первой в процедуре, т.к. запускает очередь сообщений для потока
    PeekMessage(msg, 0, WM_USER, WM_USER, PM_NOREMOVE);
    HandlesToWaitFor[0] := hCloseEvent;
    // SleepEx не нужен, если подготовительный код до цикла while будет достаточно долго выполняться
    // уточняется опытным путем, иначе очередь сообщений потока не успеет запуститься и сообщения могут улететь в пустоту
    //SleepEx(20, false);

    // тестовый пример vvv удалить
    SendString('WThread started');
    // тестовый пример ^^^

    MSWait := INFINITE; // изменяя кол-во миллисекунд в MSWait можно организовать событие-таймер, см WAIT_TIMEOUT
                        // в данном случае установлено бесконечное ожидание любого события

    while not Terminated do begin
        if not PeekMessage(msg, 0, WM_BASE, WM_MAX, PM_REMOVE) then begin
            dwHandleSignaled := MsgWaitForMultipleObjects(1, HandlesToWaitFor, false, MSWait, QS_ALLINPUT);
            case dwHandleSignaled of
                WAIT_OBJECT_0: begin // выставлено событие остановки потока
                    if not FreeOnTerminate then
                        Terminate;
                    goto EndOfThread;
                end;
                WAIT_OBJECT_0 + 1: begin // получено сообщение
                    Continue;
                end;
                WAIT_TIMEOUT: begin
                    // событие "таймер", если MSWait = количество миллисекунд
                    Continue;
                end;
            end;
        end;
        if msg.hwnd <> 0 then begin
            TranslateMessage(msg);
            DispatchMessage(msg);
            Continue;
        end;
        case msg.message of
            WM_QUIT, WM_CLOSE, WM_DESTROY: begin // оконные сообщения тоже получаем
                if not FreeOnTerminate then
                    Terminate;
                goto EndOfThread;
            end;
            // обработка сообщений из основного потока через SendToThreadXXX
            WM_INT: begin // SendToThreadInt
                // msg.lParam = Integer
            end;
            WM_STRING: begin //SendStringToThread
                str := FreeString(msg.lParam);
                SendString(str);
            end;
            WM_INT_WORD: begin // SendToThreadIntWord
                // msg.lparam = Integer
                // msg.wparam = dword
            end;
            WM_STRING_WORD: begin // SendToThreadStringWord
                // msg.wparam = dword
                str := FreeString(msg.lParam);
                SendString(str);
            end;
            // здесь можно добавить свои события, отправленные SendToThreadMessage из основного потока
        end;
    end;
EndOfThread:
    // все что создали в начале процедуры, здесь удаляем
end;

function TWThread.FreeString(var P: LPARAM): String;
begin
    if LongBool(P) then begin
        SetLength(Result, Length(PChar(P)));
        Move(Pointer(P)^, Pointer(Result)^, Length(Result)*SizeOfChar);
        P := LocalFree(HLOCAL(P));
    end;
end;

function TWThread.NewString(const Text: string): Pointer;
var l: Integer;
begin
    l := Length(Text)*SizeOfChar;
    if L > 0 then begin
        Result := Pointer(LocalAlloc(LPTR, l+SizeOfChar));
        if LongBool(Result) then
            Move(Pointer(Text)^, Result^, l);
    end else
        Result := nil;
end;

procedure TWThread.SendInteger(const Int: Integer);
begin
    if FToolWindow <> 0 then
        PostMessage(FToolWindow, WM_INT, 0, Int);
end;

procedure TWThread.SendIntegerWord(const Int: Integer; const Wrd: DWord);
begin
    if FToolWindow <> 0 then
        PostMessage(FToolWindow, WM_INT_WORD, Wrd, Int);
end;

procedure TWThread.SendMyMessage(const Msg: TMessage);
begin
    if FToolWindow <> 0 then
        PostMessage(FToolWindow, Msg.Msg, Msg.WParam, Msg.LParam);
end;

procedure TWThread.SendString(const Text: string);
var buf: Pointer;
begin
    buf := NewString(Text);
    if LongBool(buf) and (FToolWindow <> 0) then
        PostMessage(FToolWindow, WM_STRING, 0, LPARAM(buf))
    else
        FreeString(LPARAM(buf));
end;

procedure TWThread.SendStringWord(const Text: string; const Wrd: DWord);
var buf: Pointer;
begin
    buf := NewString(Text);
    if LongBool(buf) and (FToolWindow <> 0) then
        PostMessage(FToolWindow, WM_STRING, Wrd, LPARAM(buf))
    else
        FreeString(LPARAM(buf));
end;

function TWThread.StopThread: boolean;
begin
    SetEvent(hCloseEvent);
    SleepEx(1, false);
    result := WaitForSingleObject(Handle, 10000) <> WAIT_TIMEOUT;
end;

procedure TWThread.WWindowProc(var Msg: TMessage);
begin
    case Msg.Msg of
        WM_STRING: begin
            DoThreadReceiveString(FreeString(Msg.LParam));
            Msg.Result := 1;
        end;
        WM_INT: begin
            DoThreadReceiveInt(Msg.LParam);
            Msg.Result := 1;
        end;
        WM_STRING_WORD: begin
            DoThreadReceiveStringWord(FreeString(Msg.LParam), Msg.WParam);
            Msg.Result := 1;
        end;
        WM_INT_WORD: begin
            DoThreadReceiveIntWord(Msg.LParam, Msg.WParam);
            Msg.Result := 1;
        end;
        WM_MSG: begin
            DoThreadReceiveMessage(Msg.Msg, Msg.WParam, Msg.LParam);
            Msg.Result := 1;
        end
    else
        Msg.Result := DefWindowProc(FToolWindow, Msg.Msg, Msg.wParam, Msg.lParam);
    end;
end;

end.



Тестовый пример прежний, из стартового сообщения.
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38412882
Марат Сафин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Читал, читал, и "Не выдержала душа поэта" :)
На сколько я понимаю основная мысль TWThread это посылка команды в поток что бы поток эту команду выполнил (асинхронно).
Вот альтернативный вариант, так сказать как бы я это сделал:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
unit WThread;

interface

uses
  Classes, Rtti, Generics.Collections, SyncObjs;

type
  TThreadMsg = record
    Msg: Word;
    Value: TValue;
  end;

  TWThread = class(TThread)
  private
    FMsgEvent: TEvent;
    FQueue: TQueue<TThreadMsg>;
  protected
    procedure Execute; override;
    procedure TerminatedSet; override;
  public
    constructor Create; overload;
    constructor Create(CreateSuspended: Boolean); overload;
    destructor Destroy; override;

    procedure PostMessage(AMessage: Word; const AValue: TValue);
  end;

implementation

{ TWThread }

constructor TWThread.Create;
begin
  Create(False);
end;

constructor TWThread.Create(CreateSuspended: Boolean);
begin
  inherited Create(CreateSuspended);
  FQueue:=TQueue<TThreadMsg>.Create;
  FMsgEvent:=TEvent.Create(nil, False, False, '');
end;

destructor TWThread.Destroy;
begin
  FMsgEvent.Free;
  FQueue.Free;
  inherited;
end;

procedure TWThread.Execute;
var
  Msg: TThreadMsg;
begin
  while not Terminated do
  begin
    if (FMsgEvent.WaitFor = wrSignaled) and not Terminated then
    begin
      repeat
        TMonitor.Enter(FQueue);
        try
          Msg:=FQueue.Dequeue;
        finally
          TMonitor.Exit(FQueue);
        end;
        Dispatch(Msg);
      until FQueue.Count = 0;
    end;
  end;
end;

procedure TWThread.PostMessage(AMessage: Word; const AValue: TValue);
var
  Msg: TThreadMsg;
begin
  Msg.Msg:=AMessage;
  Msg.Value:=AValue;
  TMonitor.Enter(FQueue);
  try
    FQueue.Enqueue(Msg);
  finally
    TMonitor.Exit(FQueue);
  end;
  FMsgEvent.SetEvent;
end;

procedure TWThread.TerminatedSet;
begin
  inherited;
  FMsgEvent.SetEvent;
end;

end.


Наследник получается вот таким:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
unit Unit2;

interface

uses
  Windows, Messages, WThread;

const
  CM_TESTEVENT = WM_USER;

type
  TMyTestThread = class(TWThread)
  private
    procedure cmTestEvent(var Msg: TThreadMsg); message CM_TESTEVENT;
  end;

implementation

uses
  Unit1;

{ TMyTestThread }

procedure TMyTestThread.cmTestEvent(var Msg: TThreadMsg);
var
  I: Integer;
begin
  for I := 0 to 20 do
    Windows.PostMessage(Form1.Handle, CM_THREADEVENT, ThreadID, I);
end;

end.


Посылаем команду
Код: pascal
1.
  Th1.PostMessage(CM_TESTEVENT, 'Тестовая строка');


Cделано для XE3 но при определённых доработках можно перенести на более ранние версии. Например в место TValue можно использовать Variant.
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38412895
Марат Сафин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Упс, цикл не правильный поставил, нужно заменить
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
      repeat
        TMonitor.Enter(FQueue);
        try
          Msg:=FQueue.Dequeue;
        finally
          TMonitor.Exit(FQueue);
        end;
        Dispatch(Msg);
      until FQueue.Count = 0;


на while
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
      while FQueue.Count > 0 do
      begin
        TMonitor.Enter(FQueue);
        try
          Msg:=FQueue.Dequeue;
        finally
          TMonitor.Exit(FQueue);
        end;
        Dispatch(Msg);
      end;

...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38412916
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Марат Сафин
Код: pascal
1.
procedure TWThread.PostMessage(AMessage: Word; const AValue: TValue);


Сейчас Димонка придет
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38412989
Фотография Dimonka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Почему интерфейс работы с потоками у всех вас такой заумный?

Сделайте по-человечески:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
type
  TAbstractJob = class
     procedure DoJob: virtual; abstract;
  end;

  TJobThread = class(TTHread)
  public
    procedure AddJob(Job: TAbstractJob);
    property FIFO: boolean;
  end;


Всё! больше нормальному человеку ничего не надо от потока.
А уж пользователь унаследуется от TAbstractJob и добавит свой функционал.
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38413000
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimonkaПочему интерфейс работы с потоками у всех вас такой заумный?
Проще и с кучей косяков, которые многие допускают по незнанию - TThread. Куда уж проще. Но ведь кому-то не просто хочется отдать другому потоку некую работу, а и получить результат и т.п.
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38413017
Фотография Dimonka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanDimonkaПочему интерфейс работы с потоками у всех вас такой заумный?
Проще и с кучей косяков, которые многие допускают по незнанию - TThread. Куда уж проще. Но ведь кому-то не просто хочется отдать другому потоку некую работу, а и получить результат и т.п.

Т.е. с твоим интерфейсом косяков по незнанию будет меньше?
Или надо сделать всё настолько сложно, что пока разбираешься в том, что ты сделал, поймёшь как потоки работают? :)
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38413021
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimonkaТ.е. с твоим интерфейсом косяков по незнанию будет меньше?
Пока что ты нашел один и я его поправил.
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38413028
Марат Сафин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Почему интерфейс работы с потоками у всех вас такой заумный?Почему интерфейс работы с потоками у всех вас такой заумный?
Кому то нравится цвет жёлтый, кому то красный, с интерфейсами такая же фигня :(
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38413030
Фотография Dimonka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanDimonkaТ.е. с твоим интерфейсом косяков по незнанию будет меньше?
Пока что ты нашел один и я его поправил.

Основной косяк в том, что если пользователю надо будет добавить функционал к товему потоку, ему надо будет менять твой код.
Это, я считаю, в корне неправильно.
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38413031
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimonkaИли надо сделать всё настолько сложно, что пока разбираешься в том, что ты сделал, поймёшь как потоки работают? :)
Ты ведь не просто критикуешь, а понимаешь что и как? Будем рады увидеть и твой вариант реализации. :)
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38413035
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimonkaОсновной косяк в том, что если пользователю надо будет добавить функционал к товему потоку, ему надо будет менять твой код.
Я как-то не подумал об этом. Ты это серьезно?
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38413061
Фотография Dimonka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanDimonkaОсновной косяк в том, что если пользователю надо будет добавить функционал к товему потоку, ему надо будет менять твой код.
Я как-то не подумал об этом. Ты это серьезно?

Ну дык, если ты вдруг скажешь - у меня ещё N косяков обнаружилось в коде и вот она - новая версия, то пользователь тебе скажет "спасыпо".
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38413063
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimonkaНу дык, если ты вдруг скажешь - у меня ещё N косяков обнаружилось в коде и вот она - новая версия, то пользователь тебе скажет "спасыпо".
А, ты все еще об идеальном коде...
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38413082
Фотография Dimonka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanDimonkaНу дык, если ты вдруг скажешь - у меня ещё N косяков обнаружилось в коде и вот она - новая версия, то пользователь тебе скажет "спасыпо".
А, ты все еще об идеальном коде...

Я не об идеальном коде, а о практической стороне вопроса.
Если алгоритм пользователя вне твоего кода, то пользователю надо заменить только твой юнит. А если внутри твоего кода, то надо будет редактировать весь код, где использовался твой "шаблон".
...
Рейтинг: 0 / 0
Шаблон класса для работы с потоком (WThread, Thread)
    #38413092
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimonkaА если внутри твоего кода, то надо будет редактировать весь код, где использовался твой "шаблон".
Пояснить, что такое шаблон? Заканчивай оффтопить, выдвигай пожелания и свои варианты. Описал-же идеальный вариант, похвастайся и реализацией.
...
Рейтинг: 0 / 0
25 сообщений из 469, страница 2 из 19
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Шаблон класса для работы с потоком (WThread, Thread)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]