2017-08-23 7 views
0

私はバックエンド(WebBrokerを使用)を構築しており、いくつかのAPIがあります。クライアントでは、JSONを取得して解析するためにRESTコンポーネントを使用します。これは一例です:Delphi REST Request async

procedure TForm1.ButtonCreateClick(Sender: TObject); 
begin 

//rreqTodoCreate is a TRESTRequest component! 

rreqTodoCreate.Params[0].Value := EditTitle.Text; 
rreqTodoCreate.Params[1].Value := EditCategory.Text; 

rreqTodoCreate.ExecuteAsync(procedure 
          begin 
           ResponseEdit.Text := rrespToDo.Content; 
          end); 

end; 

私は携帯の午前と私はUIがフリーズしたくないので、docwikiも示唆するように、私はExecuteAsyncを使用しています!私は別のスレッドで実行されるExecuteAsyncを読んでいるので、私は疑いがあります。

スレッドセーフで書かれたコードはありますか?つまり、メインフォームのコンポーネントのテキストを更新するときに、キューまたは同期を使用する必要がありますか?

+0

Er、UIアクセスはUIスレッドで発生する必要がありますか? –

+1

@DavidHeffernanはい!だから私はTThread.Queueを呼び出すと良いと思う.Queue –

答えて

1

はい、私もこれが優れていると思う:

rreqTodoCreate.ExecuteAsync(procedure 
          begin 
           TThread.Queue(procedure 
              begin 
               ResponseEdit.BeginUpdate; 
               ResponseEdit.Text := rrespToDo.Content; 
               ResponseEdit.EndUpdate; 
              end; 
          end); 

説明:

  1. TThread.Queueは、BeginUpdateメソッドとEndUpdateメソッドは、UIをフリーズメインスレッド
  2. で匿名メソッドを実行し、形式の更新を高速化する
+0

私はそれが良いと思うが、少しの説明が役立つかもしれない、特にBeginUpdateとEndUpdateを追加した理由について。 – GolezTrol

+1

@GolezTrol私は解答を更新しました:) – zawuza

+1

'ExecuteAsync()'補完ハンドリングはデフォルトで同期されているので、 'TThread.Queue()'に対する余分な呼び出しは実際には冗長です。また '(Begin | End)Update()を呼び出すことは、1つだけ更新するときにはあまり効果的ではありません。一度に複数のものを更新するときに使用する必要があります。 –

4

TRESTRequest.ExecuteAsync() documentation

パラメータ

この方法は、以下のパラメータを定義します。

  • ACompletionHandlerは - リクエストの実行を完了した後に実行する匿名メソッドを指定します。
  • ASynchronized - Trueの場合、ACompletionHandlerで設定されたメソッドがメインスレッドのコンテキストで実行されることを指定します。 Falseの場合、ACompletionHandlerが実行スレッドコンテキストで実行されます。
  • AFreeThread - Trueの場合、要求実行の完了後に実行スレッドが解放されます。

ASynchronizedパラメータは、デフォルトでTrueです:

function ExecuteAsync(
    ACompletionHandler: TCompletionHandler = nil; 
    ASynchronized: Boolean = True; // <-- 
    AFreeThread: Boolean = True; 
    ACompletionHandlerWithError: TCompletionHandlerWithError = nil): TRESTExecutionThread; 

だから、あなたが示されているコードは、そのまま完全に罰金です、ResponseEdit.Textの割り当ては、スレッドセーフです。

関連する問題