Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2006.07.16;
Скачать: [xml.tar.bz2];

Вниз

Поток в созаднном мной классе   Найти похожие ветки 

 
NORDmen ©   (2006-06-28 21:16) [0]

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

возникают траблы с потоками. т.к. например:
1 стандартный поток delphi - для него нужен свой класс. отсюда возникают траблы. как бы сделать все в одном классе без геморра? ))
2 создание потока срествами winapi - CreateThread(...) но тут тоже трабла :) - нельзя передать указатель на процедуру этого класса, выдает ошибку типа надо это не переменная. можно создать просто процедуру (не принадлежещую к этому классу), но тогда проблемы в том, что эта процедура не видит переменных класса.

как мне сделать сабж?


 
Пусик ©   (2006-06-28 21:24) [1]


> как мне сделать сабж?


Посмотри, как реализован в VCL класс TThread. Сразу все понятно будет.


 
NORDmen ©   (2006-06-28 21:45) [2]

Пусик, огромный респект )))


> Сразу все понятно будет.


мне вот что непонятно - там вызывается
 FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, FThreadID);

ThreadProc - function ThreadProc(Thread: TThread): Integer;
так вот, как этой ф-ии ThreadProc передается параметр, если она передается в beginthread по указателю?

т.е. как в ThreadProc правильно передаются параметры?


 
Пусик ©   (2006-06-28 22:07) [3]


> NORDmen ©   (28.06.06 21:45) [2]


FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, FThreadID);
Self - в данном случае указатель на экземпляр твоего класса.
ThreadProc получает его параметром, затем(после приведения) в поточной функции можно использовать методы и поля твоего класса.

function ThrProc(p: Pointer): Integer;
begin
  TMyClass(p).Field1 := ...
end;


Только надо учитывать, что с полями ты будешь работать из нескольких потоков. Поэтому нужна синхронизация.


 
Leonid Troyanovsky ©   (2006-06-29 00:12) [4]


> NORDmen ©   (28.06.06 21:16)  

> 1 стандартный поток delphi - для него нужен свой класс.
> отсюда возникают траблы. как бы сделать все в одном классе
> без геморра? ))


Пардон, а в чем, собс-но, оный геморр?
В создании, использовании другого класса?

Ярых поборников ООП - прошу отреагировать.

--
Regards, LVT.


 
Fay ©   (2006-06-29 00:14) [5]

2 Leonid Troyanovsky ©   (29.06.06 0:12) [4]
> Ярых поборников ООП - прошу отреагировать
Ничего не скажу. Не использую TThread-идов.


 
Джо ©   (2006-06-29 00:24) [6]

> [5] Fay ©   (29.06.06 00:14)
> 2 Leonid Troyanovsky ©   (29.06.06 0:12) [4]
> > Ярых поборников ООП - прошу отреагировать
> Ничего не скажу. Не использую TThread-идов.

Я, хоть и не "ярый поклонник", но изпользую TTread"ы и считаю их чертовски удобными :-)


 
Пусик ©   (2006-06-29 00:57) [7]


> Leonid Troyanovsky ©   (29.06.06 00:12) [4]


Я так понимаю, что у автора проблема с агрегированием.

ООП так ООП.

Вот пример:

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, SyncObjs;

type

 TPusikSample=class;

 TPusikThread=class(TThread)
 private
   FPusikSample: TPusikSample;
 protected
   procedure Execute; override;
 public
   constructor Create(aParent:TPusikSample);
 end;

 TPusikSample=class
 private
   FCS: TCriticalSection;
   FField1: String;
   FField2: String;
   FField3: String;
   FField4: String;
   FThread: TPusikThread;
   procedure Lock;
   procedure Unlock;
   procedure SetField1(const Value: String);
   procedure SetField2(const Value: String);
   procedure SetField3(const Value: String);
   procedure SetField4(const Value: String);
   function GetField1: String;
   function GetField2: String;
   function GetField3: String;
   function GetField4: String;
 public
   constructor Create;
   destructor Destroy; override;

   procedure StartThread;
   procedure OnTerminateThread(Sender: TObject);

   property Field1: String read GetField1 write SetField1;
   property Field2: String read GetField2 write SetField2;
   property Field3: String read GetField3 write SetField3;
   property Field4: String read GetField4 write SetField4;
 end;

 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   Memo1: TMemo;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 PusikSample: TPusikSample;

implementation

{$R *.dfm}

{ TPusikSample }

constructor TPusikSample.Create;
begin
 FCS := TCriticalSection.Create;
end;

destructor TPusikSample.Destroy;
begin
 FCS.Free;
 inherited;
end;

function TPusikSample.GetField1: String;
begin
 Lock;
 try
   Result := FField1;
 finally
   Unlock;
 end;
end;

function TPusikSample.GetField2: String;
begin
 Lock;
 try
   Result := FField2;
 finally
   Unlock;
 end;
end;

function TPusikSample.GetField3: String;
begin
 Lock;
 try
   Result := FField3;
 finally
   Unlock;
 end;
end;

function TPusikSample.GetField4: String;
begin
 Lock;
 try
   Result := FField4;
 finally
   Unlock;
 end;
end;

procedure TPusikSample.Lock;
begin
 FCS.Enter;
end;

procedure TPusikSample.OnTerminateThread(Sender: TObject);
begin
 ShowMessage("Расчет завершен");
end;

procedure TPusikSample.SetField1(const Value: String);
begin
 Lock;
 try
   FField1 := Value;
 finally
   Unlock;
 end;
end;

procedure TPusikSample.SetField2(const Value: String);
begin
 Lock;
 try
   FField2 := Value;
 finally
   Unlock;
 end;
end;

procedure TPusikSample.SetField3(const Value: String);
begin
 Lock;
 try
   FField3 := Value;
 finally
   Unlock;
 end;
end;

procedure TPusikSample.SetField4(const Value: String);
begin
 Lock;
 try
   FField4 := Value;
 finally
   Unlock;
 end;
end;

procedure TPusikSample.StartThread;
begin
 FThread := TPusikThread.Create(Self);
 FThread.OnTerminate := OnTerminateThread;
 FThread.Resume;
end;

procedure TPusikSample.Unlock;
begin
 FCS.Leave;
end;

{ TPusikThread }

constructor TPusikThread.Create(aParent: TPusikSample);
begin
 inherited Create(True);
 FreeOnTerminate := True;
 FPusikSample := aParent;
end;

procedure TPusikThread.Execute;
begin
 Sleep(1000);
 FPusikSample.Field1 := "Расчет на шаге 1 закончен";
 Sleep(1000);
 FPusikSample.Field2 := "Расчет на шаге 2 закончен";
 Sleep(1000);
 FPusikSample.Field3 := "Расчет на шаге 3 закончен";
 Sleep(1000);
 FPusikSample.Field4 := "Расчет на шаге 4 закончен";
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 PusikSample := TPusikSample.Create;
 PusikSample.StartThread;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 Memo1.Lines.Clear;
 Memo1.Lines.Add(PusikSample.Field1);
 Memo1.Lines.Add(PusikSample.Field2);
 Memo1.Lines.Add(PusikSample.Field3);
 Memo1.Lines.Add(PusikSample.Field4);
 PusikSample.Free;
end;

end.


 
Leonid Troyanovsky ©   (2006-06-29 01:02) [8]


> Fay ©   (29.06.06 00:14) [5]

> Ничего не скажу. Не использую TThread-идов.

> Джо ©   (29.06.06 00:24) [6]

> Я, хоть и не "ярый поклонник", но изпользую TTread"ы и считаю
> их чертовски удобными :-)


Понимаю, согласен  :)

Жаль вот лишь, что ярые поклонники не реагируют.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2006-06-29 02:16) [9]


> Пусик ©   (29.06.06 00:57) [7]

> ООП так ООП.

> Вот пример:


Не понравился.
Во-первых, какие-то приседания вокруг непонятного TPusikSample,
когда это должен быть простой потомок TThread.
Во-вторых, странно, что поборники ООП, видимо, не знакомы
с индексированными свойствами.
Да, и сама идея с критической секцией в данном случае выглядит
громоздко и неестественно против Synchronize.

Да, и какое такое агрегирование?

--
Regards, LVT.


 
Джо ©   (2006-06-29 02:29) [10]

> Да, и какое такое агрегирование?

Наверное, агрегация (хотя я встречал и вариант "агрегирование"). Только я и сам не очень пойму, почему не использовано наследование, но тут уж хозяин барин. Возможно, и были причины, я код не смотрел, только объявления.


 
Пусик ©   (2006-06-29 02:34) [11]


> когда это должен быть простой потомок TThread.


1. Простой потомок TThread сможет выполнить поточную функцию только один раз. В примере поток создается по мере необходимости. К тому же в классе может бытьнеобходимость в создании нескольких разных потоков.
2. Условие в топике предполагает именно такое решение.


> Во-вторых, странно, что поборники ООП, видимо, не знакомыс
> индексированными свойствами.


Противники ООП видимо забывают, что здесь поборники ООП приводят примеры. В приведенном примере поля FField1..4 могут быть разного типа.


> Да, и сама идея с критической секцией в данном случае выглядитгромоздко
> и неестественно против Synchronize.


В данном случае решение с критической секцией намного элегантнее и проще. Для Synchronize потребовалось бы либо писать дополнительно 4 функции для работы с каждым полем по-отдельности, либо исользовать промежуточные/временные поля. В случае 5-10... и т.д. количества полей и алгоритмом расчета по шагам с синхронизацией на каждом шаге с Synchronize вообще не подходит.


> Да, и какое такое агрегирование?


Нууу...

Такие вещи, я бы сказала, просто стыдноне знать...

В традиционном ООП предусмотрены три типа отношений между классами:
- Использование: непосредственная зависимость.
- Включение: иногда называется агрегированием. Реализует логические связи типа «является составной частью».
- Наследование: реализует логические связи типа «является частным случаем».

В таких языках, как VB .NET, C# и Java, кроме классических типов существует четвертый тип отношений между классами — реализация интерфейса (отношение типа «поддерживает»).


 
Игорь Шевченко ©   (2006-06-29 09:45) [12]


> В таких языках, как VB .NET, C# и Java, кроме классических
> типов существует четвертый тип отношений между классами
> — реализация интерфейса (отношение типа «поддерживает»).
>


В Delphi тоже...


 
Leonid Troyanovsky ©   (2006-06-29 18:39) [13]


> Пусик ©   (29.06.06 02:34) [11]


> 1. Простой потомок TThread сможет выполнить поточную функцию
> только один раз. В примере поток создается по мере необходимости.
>  К тому же в классе может бытьнеобходимость в создании нескольких
> разных потоков.

Ну, и юзай поля-свойства формы - это ж, всего лишь, пример.

> приводят примеры. В приведенном примере поля FField1..4
> могут быть разного типа.

Да - споткнулся, упал на нож. И так 13 раз подряд.

> В данном случае решение с критической секцией намного элегантнее
> и проще. Для Synchronize потребовалось бы либо писать дополнительно
> 4 функции для работы с каждым полем по-отдельности, либо

А зачем 4? Одной вполне достаточно.
Да и полей хватит, можно даже без свойств.

Т.е., весь этот пример можно было свести к десятку строк.
И мысли б были понятней, и мне б, возможно понравилось.
Краткость, как говорится, сестра.

> Такие вещи, я бы сказала, просто стыдноне знать...

Не зарывайтесь, Штирлиц. Не зарывайтесь.
Я старше Вас по возрасту, да и по званию.

Эти учебники я читал лет 10 назад.
А спросил лишь потому, что мне, собс-но, совсем непонятно,
что именно вызвало затруднение вопрошающего.

Но, конечно, после разъяснения - мол, проблемы с
агрегированием - мне сразу стало раза в два понятней.

> В традиционном ООП предусмотрены три типа отношений между

Думаю, что в нетрадиционном их даже более.

--
Regards, LVT.


 
Пусик ©   (2006-06-29 19:02) [14]


> Leonid Troyanovsky ©   (29.06.06 18:39) [13]
> возрасту, да и по званию.


Позвольте поинтересоваться Вашим возрастом и званием?


 
Fay ©   (2006-06-29 19:07) [15]

2 Пусик ©   (29.06.06 19:02) [14]
5+


 
Пусик ©   (2006-06-29 19:12) [16]


> Leonid Troyanovsky ©   (29.06.06 18:39) [13]


Целью выше приведенного кода являлось показать пример, как делаетсяф то, что нужно автору. А понравится этот код или нет LVT, мне, в принципе, абсолютно фиолетово.
Всегда проще критиковать чужой код, чем написать свой.
А как использовать показанные приемы - личное дело автора вопроса.


 
Leonid Troyanovsky ©   (2006-06-29 19:49) [17]


> Пусик ©   (29.06.06 19:02) [14]

> Позвольте поинтересоваться Вашим возрастом и званием?


Лейтенант я, старшой.. Угу.

45 полных (23 стаж, застал ЕС1055 и IBM355,
правда, в японской войне не участвовал)

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2006-06-29 19:56) [18]


> Пусик ©   (29.06.06 19:12) [16]

> Всегда проще критиковать чужой код, чем написать свой.


Заблуждение.
Иногда читаешь нечто и думаешь, чего ж так автор мучается,
проще уж самому написать.

Но, есть, конечно, и хорошие примеры - льются как песня.

Так, вот, уважаемый Пусик - стремиться надо к последним.
Это я тебе как старший товарищ говорю.

--
Regards, LVT.


 
Fay ©   (2006-06-29 20:03) [19]

2 Leonid Troyanovsky ©   (29.06.06 19:56) [18]
Приведите свой пример-песню. Заодно укажете направление для устремлений.


 
Leonid Troyanovsky ©   (2006-06-29 20:47) [20]


> Fay ©   (29.06.06 20:03) [19]

> Приведите свой пример-песню. Заодно укажете направление
> для устремлений.


Мне нравятся примеры by Peter Below (TeamB).
Можешь нагуглить на многие темы.

Один зарубежный дельфер даже создал коллекцию из
его постов в chm (5-6MB). Очень увлекательно читается.

Ну, а устремление у нас должно быть одно:
каждый день, каждый час играть в шаш.., т.е. шахматы.

--
Regards, LVT.



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2006.07.16;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.01 c
15-1150227077
ancot
2006-06-13 23:31
2006.07.16
Что за файл .rsm


2-1151305265
novill
2006-06-26 11:01
2006.07.16
Как узнать размер текстового файла (Textfile)?


2-1151587495
Kill
2006-06-29 17:24
2006.07.16
Направление в котором нужно работать


15-1150456037
aka
2006-06-16 15:07
2006.07.16
about Com


2-1151665131
Id
2006-06-30 14:58
2006.07.16
Русские буквы в названии полей





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский