2017-08-23 37 views
0

我已經建立了後端(與WebBroker),它有一些API。所以在客戶端中,我將使用REST組件來獲取json並解析它。這是一個例子:德爾福REST請求異步

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; 

我用ExecuteAsync作爲docwiki還建議,因爲我是在移動,我不希望UI凍結!我已閱讀ExecuteAsync運行在一個單獨的線程,所以我有一個疑問。

我寫的代碼是線程安全的嗎?換句話說:當我更新主窗體中組件的文本時,是否應該使用Queue或Synchronize?

+0

呃,UI的訪問必須發生在UI線程上嗎? –

+1

@DavidHeffernan是的!所以我想如果我打電話給TThread.Queue –

回答

1

是的,我也認爲這是更好的:

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

說明:

  1. TThread.Queue執行主線程
  2. 的BeginUpdate和EndUpdate匿名方法凍結UI和加快形式更新
+0

會更好,但我認爲它更好,但有些解釋可能會有用,特別是關於爲什麼添加了BeginUpdate和EndUpdate。 – GolezTrol

+1

@GolezTrol我已經更新了我的回答,並附有說明:) – zawuza

+1

'ExecuteAsync()'完成處理是默認同步的,所以額外調用TThread.Queue()實際上是多餘的。另外,當你只更新一件事時,調用'(Begin | End)Update()'並不是很有益。它們應該在一次更新多個事物時使用。 –

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的分配是線程安全的。