Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Как передать дин. массив в поток. (TThread)


Автор: pukin 28.3.2008, 15:51
Здравствуйте!

Подскажите как передать в поток заполненный дин. массив.

Пример:
Код

type TTest = record
               A,B,C : String;
               M     : Integer;
             end;

type
  TThrd = class(TThread)
  private
    FArr: array of TTest;
  protected
    procedure Execute; override;
  public
    property Arr: array of TTest write FArr; // Error
  end;

Сказать текст ошибки сейчас не могу. Т.к. пишу на коленке, но помню, что не получалось "с налёту убить Федота", т.е. передать массив потоку.
Покажите на реальном примерчике, чтобы в голове сразу устаканилось.

Заранее, премного благодарен.

 smile 

Автор: DmitryHT 28.3.2008, 16:00
через цикл по одному значению?

Автор: pukin 28.3.2008, 16:17
Цитата(DmitryHT @ 28.3.2008,  16:00)
через цикл по одному значению?

Массив динамический я изначально не знаю сколько в нём данных.

Автор: Rennigth 28.3.2008, 16:17
pukin
Цитата(pukin @  28.3.2008,  15:51 Найти цитируемый пост)
, но помню, что не получалось 

Значит что-то не так делал. Create вызывай с Susperded True, потом копируй массив, потом Resume делай. 

Автор: VICTAR 28.3.2008, 16:18
1) Попробуй привести к одному типу
2) А лучше сделай нормальный сеттер

Автор: pukin 28.3.2008, 16:21
smile 

Кто-нибудь из знающих может сейчас на своей машине (с дельфёй под рукой) попробовать сделать пример где потоку передаётся заполненный дин. массив.

Добавлено через 2 минуты и 27 секунд
Цитата(Rennigth @ 28.3.2008,  16:17)
pukin
Цитата(pukin @  28.3.2008,  15:51 Найти цитируемый пост)
, но помню, что не получалось 

Значит что-то не так делал. Create вызывай с Susperded True, потом копируй массив, потом Resume делай.

TThread.Suspend и TThread.Resume здесь не причём =))))

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

Автор: Rennigth 28.3.2008, 16:32
держи:
Код

unit Unit29;

interface

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

type
  TSomeThread = class;

  TForm29 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FThread: TSomeThread;

  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

  TSomeStruct = packed record
    SomeVar1: Integer;
    SomeVar2: string;
  end;

  TSomeStructList = array of TSomeStruct;

  TSomeThread = class(TThread)
  private
    FSomeStructList: TSomeStructList;
    function GetSomeStructList: TSomeStructList;
    procedure SetSomeStructList(const Value: TSomeStructList);
  protected
    procedure DoSomeWork;
    procedure Execute; override;
  public
    property SomeStructList: TSomeStructList read GetSomeStructList
      write SetSomeStructList;
  end;

var
  Form29: TForm29;

implementation

{$R *.dfm}

constructor TForm29.Create(AOwner: TComponent);
var
  lSomeStructList: TSomeStructList;
begin
  inherited;
  SetLength(lSomeStructList, 5);
  lSomeStructList[0].SomeVar2 := '0';
  lSomeStructList[1].SomeVar2 := '1';
  lSomeStructList[2].SomeVar2 := '2';
  lSomeStructList[3].SomeVar2 := '3';
  lSomeStructList[4].SomeVar2 := '4';

  FThread := TSomeThread.Create(True);
  FThread.SomeStructList := lSomeStructList;
  FThread.Resume;
end;

destructor TForm29.Destroy;
begin
  FThread.Terminate;
  WaitForSingleObject(FThread.Handle, INFINITE);
  FThread.Free;
  inherited;
end;

procedure TForm29.FormCreate(Sender: TObject);
begin

end;

{ TSomeThread }

procedure TSomeThread.DoSomeWork;
begin
  Application.MainForm.Caption := FSomeStructList[Random(Length(FSomeStructList))].SomeVar2;
end;

procedure TSomeThread.Execute;
begin
  inherited;
  while not Terminated do
  begin
    Sleep(100);
    if not Terminated then
      Synchronize(DoSomeWork);
  end;
end;

function TSomeThread.GetSomeStructList: TSomeStructList;
begin
  Result := FSomeStructList;
end;

procedure TSomeThread.SetSomeStructList(const Value: TSomeStructList);
begin
  FSomeStructList := Value;
end;

end.


Автор: VICTAR 28.3.2008, 16:39
Вот конкретно с динамическим массивом

Автор: pukin 28.3.2008, 17:09
Всё понял, спасибо большое за ответы.  smile 

Автор: MetalFan 28.3.2008, 19:59
pukin, только учти, что не один пример не предусматривает корректную синхронизацию данных, что может привести к непредвиденным багам

Автор: Rennigth 28.3.2008, 20:02
Цитата(MetalFan @  28.3.2008,  19:59 Найти цитируемый пост)
pukin, только учти, что не один пример не предусматривает корректную синхронизацию данных, что может привести к непредвиденным багам 

ты по поводу того что массив желательно былобы копирнуть?

Автор: MetalFan 28.3.2008, 20:56
Rennigth, можно и копирнуть... ну в твоем примере криминала то почти нет. ибо в треде нет работы с массивом.

кстати
Цитата(Rennigth @  28.3.2008,  16:32 Найти цитируемый пост)
destructor TForm29.Destroy;
begin
  FThread.Terminate;
  WaitForSingleObject(FThread.Handle, INFINITE);
  FThread.Free;
  inherited;
end;

кстати тут достаточно просто FThread.Free

Автор: VICTAR 28.3.2008, 22:48
MetalFan, что не так в моем примере? smile 

Автор: MetalFan 29.3.2008, 09:50
VICTAR, у тебя передается ссылка на дин.массив в трэд, и потом в 2х разных потоках ведется с ним работа... если я не ошибаюсь

Добавлено через 5 минут и 51 секунду
нет, не ошибаюсь. так работать с данными из разных потоков недопустимо!

Автор: VICTAR 29.3.2008, 10:21
Цитата(MetalFan @  29.3.2008,  09:50 Найти цитируемый пост)
так работать с данными из разных потоков недопустимо! 

Согласен.
Был не прав, прошу прощения.
Обиделся и встал в угол

Автор: MetalFan 29.3.2008, 11:11
Цитата(VICTAR @  29.3.2008,  10:21 Найти цитируемый пост)
Обиделся и встал в угол 

 smile  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)