Pascal Code
1 2 3 4 5 6 7 8 9 10 11 12
|
|
procedure TMainForm.Button1Click(Sender: TObject); begin TThread.CreateAnonymousThread(procedure begin Synchronize(procedure begin Edit1.Text := 'aa'; end ); end ).Start; end; | 在這個環(huán)境中,作為 CreateAnonymousThread 參數(shù)的匿名函數(shù)所形成的閉包(Closure)所處于的上下文環(huán)境是 TMainForm.Button1Click。也就是說,閉包能訪問外部域是 TMainForm.Button1Click 所能訪問的域。你企圖訪問的 Synchronize 是 TThead.Synchronize,不論是類方法還是對象方法,都不處于 TMainForm.Button1Click 能訪問的作用域。碰巧你這個閉包中訪問 Self 是合法的,但它是 TMainForm 的實例調(diào)用 TMainForm 的實例的 Self,不是 TThread 的實例的 Self。 所以現(xiàn)在要做的就是解決訪問域的問題。
解決方案1:
Pascal Code
1 2 3 4 5 6 7 8 9 10 11
|
|
procedure TMainForm.Button1Click(Sender: TObject); var t: TThread; begin t := TThread.CreateAnonymousThread(procedure begin ... end ); t.Start; end; |
這樣,閉包的上下文環(huán)境中包換了局部變量 t,可以通過它來完成對 TThread 實例的 Synchronize 方法的訪問。但是現(xiàn)在還有一個問題,TThread.Synchronize 方法是 protected,TMainForm 所在的單元不是 Classes,無法直接訪問。這時候只要簡單利用同一單元內(nèi)可以訪問 protected 的特性即可:
Pascal Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
|
type TThreadPlus = class(TThread);
...
procedure TMainForm.Button1Click(Sender: TObject); var t: TThread; begin t := TThread.CreateAnonymousThread(procedure begin TThreadPlus(t).Synchronize(procedure begin Edit1.Text := 'aa'; end end ); t.Start; end; |
解決方案2:利用了TThead類的Class function處于Pulic的特性,免除了新類的聲明
Pascal Code
1 2 3 4 5 6 7 8 9 10 11 12 13
|
|
procedure TMainForm.Button1Click(Sender: TObject); var t: TThread; begin t:= TThread.CreateAnonymousThread(procedure begin TThread.Synchronize(t, procedure begin Caption := 'aa'; end ); end); t.Start; end; |
|