OmniThreadLibrary forum
News: SMF - Just Installed!
 
*
Welcome, Guest. Please login or register. May 17, 2012, 05:56:59 PM


Login with username, password and session length


Pages: 1 [2]   Go Down

Author Topic: Passing parameters to function which will be executed by Async  (Read 1018 times)

Soft landing

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: Passing parameters to function which will be executed by Async
« Reply #15 on: December 13, 2011, 10:35:21 AM »

So how would you tackle this? i.e. A simple case where you want to use a background thread to prepare some text, then display the result in a TMemo? I'm not sure how you could do it without a TStrings object somewhere, even if you are free to re-write BackgroundTask, which may not always be the case.
Logged

Primoz Gabrijelcic

  • Administrator
  • Hero Member
  • *****
  • Posts: 569
    • View Profile
    • Email
Re: Passing parameters to function which will be executed by Async
« Reply #16 on: December 13, 2011, 10:50:12 AM »

I would do it just like you did and would forget about try..finally.
Logged

Soft landing

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: Passing parameters to function which will be executed by Async
« Reply #17 on: December 13, 2011, 11:09:57 AM »

hmmm ... OK. I think you have just convinced me not to spend any more time with OTL.
Logged

Primoz Gabrijelcic

  • Administrator
  • Hero Member
  • *****
  • Posts: 569
    • View Profile
    • Email
Re: Passing parameters to function which will be executed by Async
« Reply #18 on: December 13, 2011, 11:56:10 AM »

Why? If you do the same with TThread and Queue, you would have the same problem. If you are sending objects across the thread boundary, then there's no good point to write try..finally because object's lifetime is split into two.

You'll run into the same problem with any threading framework. If you don't like that, use interface wrappers for objects and send interfaces around.
Logged

Soft landing

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: Passing parameters to function which will be executed by Async
« Reply #19 on: December 13, 2011, 01:10:07 PM »

Well perhaps I am missing something here. It wouldn't be the first time. It seems to me though I could do this with just TThread, like this:
Code: [Select]
type

  TTextReadyEvent = procedure (sender : TObject; Text : TStrings) of object;

  TTextSetter = class(TThread)
  private
    FOnTextReady: TTextReadyEvent;
  protected
    FResult : TStrings;
    procedure Showresult;
  public
    procedure Execute; override;
    property OnTextReady : TTextReadyEvent read FOnTextReady write FOnTextReady;
  end;

procedure TTextSetter.Execute;
begin
  FResult := TStringList.Create;
  try
    BackgroundTask(FResult);
    synchronize(Showresult);
  finally
    FResult.free;
  end;
end;

procedure TTextSetter.Showresult;
begin
  if assigned(FOnTextReady) then
    FOnTextReady(Self, FResult);
end;


procedure TForm3.AddNewText(Sender: TObject; Newtext: TStrings);
begin
  Memo1.Lines.AddStrings(Newtext);
end;

procedure TForm3.Button1Click(Sender: TObject);
var
  Background : TTextSetter;
begin
  Background := TTextSetter.Create(TRUE);
  Background.FreeOnTerminate := TRUE;
  Background.OnTextReady := AddNewText;
  Background.Start;
end;
This runs BackgroundTask in a background thread to prepare the text, updates the GUI in a safe way, and I don't have to abandon the try...finally to do it. So what am I missing?
Logged

Primoz Gabrijelcic

  • Administrator
  • Hero Member
  • *****
  • Posts: 569
    • View Profile
    • Email
Re: Passing parameters to function which will be executed by Async
« Reply #20 on: December 13, 2011, 01:26:41 PM »

Yes, it is possible to do with Synchronize, but Synchronize brings you a bunch of other problems - for example it would block your thread until the code is executed.

If you want to stay with this style of coding then OTL really has nothing to offer you.
Logged

Soft landing

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: Passing parameters to function which will be executed by Async
« Reply #21 on: December 13, 2011, 01:34:45 PM »

It isn't that I want to stay with any particular style of coding. I want to get the job done, and I am willing to try new ways of doing that. That's why I looked at OTL, but I don't want to adopt something new that leaves me without safeguards in case of error. I don't care how easy or powerful it is if it isn't safe. Background task could be my code or someone else's, and I have to assume either could contain bugs. I regard discarding any method of catching those bugs as bad practise.
Logged

Primoz Gabrijelcic

  • Administrator
  • Hero Member
  • *****
  • Posts: 569
    • View Profile
    • Email
Re: Passing parameters to function which will be executed by Async
« Reply #22 on: December 13, 2011, 01:43:46 PM »

OK, I do agree that this is a good philosophy :)

Maybe you should look into Smart Pointers? There's a good article (+ implementation) at http://members.adug.org.au/2011/12/05/smart-pointers/ .

With smart pointers you could do something like this (untested, written in browser):

Code: [Select]
procedure TForm3.btnTestClick(Sender: TObject);
begin
  parallel.Async(
    procedure (const Task : IOmniTask)
    var
      result : ISmartPointer<TStringList>;
    begin
      result := TSmartPointer<TStringList>.Create(TStringList.Create);
      BackgroundTask(result);

      Task.Invoke(
        procedure
        begin
          Memo1.Lines.AddStrings(result);
        end);
    end);
end;

Now there's no need for manual destruction because TStringList is wrapped into an interface and compiler/RTL will make sure that it is destroyed at the appropriate moment.
Logged

Soft landing

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: Passing parameters to function which will be executed by Async
« Reply #23 on: December 14, 2011, 06:31:47 AM »

I have had a look at that link, thanks. I can't make up my mind if it is clever or ugly - or possibly both. It is certainly interesting. I'll work through a bit more OTL stuff using smart pointers and see what conclusions I reach.
Logged

Primoz Gabrijelcic

  • Administrator
  • Hero Member
  • *****
  • Posts: 569
    • View Profile
    • Email
Re: Passing parameters to function which will be executed by Async
« Reply #24 on: December 14, 2011, 10:07:12 AM »

The alternative is, of course, to write IStringList (sadly not provided by Embarcadero) and use that.
Logged
Pages: 1 [2]   Go Up
 
 

Powered by MySQL Powered by PHP Powered by SMF 2.0.2 | SMF © 2006-2009, Simple Machines LLC

Valid XHTML 1.0! Valid CSS! Dilber MC Theme by HarzeM