Você está na página 1de 17

Como fazer chamadas thread-safe para controles dos Windows Forms

.NET Framework 4.5 Outras verses Este tpico ainda no foi avaliado como - Avalie este tpico Se voc usar multithreading para melhorar o desempenho de seus aplicativos Windows Forms, voc deve certificar-se de que voc faa chamadas para seus controles em uma forma thread-safe. Acesso aos controles do Windows Forms no inerentemente segura para thread. Se tiver duas ou mais segmentos para manipular o estado de um controle, possvel forar o controle em um estado inconsistente. Outros bugs relacionados a thread so possveis, como, por exemplo, deadlocks e condies de corrida. importante certificar-se de que o acesso aos controles executado de forma segura para thread. No seguro chamar um controle a partir de um segmento diferente daquele que criou o controle sem usar o Invoke mtodo. Este um exemplo de uma chamada que no thread-safe. C# C++ VB / /T h i se v e n th a n d l e rc r e a t e sat h r e a dt h a tc a l l sa / /W i n d o w sF o r m sc o n t r o li na nu n s a f ew a y . p r i v a t ev o i ds e t T e x t U n s a f e B t n _ C l i c k ( o b j e c ts e n d e r , E v e n t A r g se ) { t h i s . d e m o T h r e a d= n e wT h r e a d ( n e wT h r e a d S t a r t ( t h i s . T h r e a d P r o c U n s a f e ) ) ; t h i s . d e m o T h r e a d . S t a r t ( ) ; } / /T h i sm e t h o di se x e c u t e do nt h ew o r k e rt h r e a da n dm a k e s / /a nu n s a f ec a l lo nt h eT e x t B o xc o n t r o l . p r i v a t ev o i dT h r e a d P r o c U n s a f e ( ) {

t h i s . t e x t B o x 1 . T e x t=" T h i st e x tw a ss e tu n s a f e l y . " ; }

O .NET Framework ajuda a voc detectar quando voc est acessando seus controles de forma que no thread-safe. Quando voc estiver executando o aplicativo no depurador e um thread diferente no qual criou um controle tenta chamar o controle, o depurador gera umaInvalidOperationException com a mensagem, "controle nome do controleacessado a partir de um segmento diferente, por exemplo, o segmento que foi criado." Essa exceo confivel ocorre durante a depurao e, em algumas circunstncias, em tempo de execuo. Talvez voc veja essa exceo quando voc depura aplicativos que voc escreveu com o .NET Framework antes de .NET Framework 2.0. altamente recomendvel para corrigir esse problema, quando voc v-lo, mas voc pode desativ-la, definindo aCheckForIllegalCrossThreadCalls propriedade para false. Isso faz com que seu controle seja executado como ele ser executado em Visual Studio.NET 2003 e o .NET Framework 1.1.

Observao Se voc estiver usando os controles de ActiveX em um formulrio, voc poder receber o thread cruzado InvalidOperationException quando voc executa sob o depurador. Quando isso ocorre, o controle de ActiveX no suporta multithreading. Para obter mais informaes sobre como usar controles de ActiveX com o Windows Forms, consulteWindows Forms e aplicativos no gerenciados. Se voc estiver usando o Visual Studio, voc pode impedir que essa exceo, desativando o processo de hospedagem do Visual Studio.

Fazer chamadas do Thread-Safe para controles Windows Forms


Para fazer uma chamada de thread-safe para um controle Windows Forms
1. Consultar o controle InvokeRequired propriedade. 2. Se InvokeRequired retorna true, chame Invoke com um delegado que faz a chamada real para o controle. 3. Se InvokeRequired retorna false, ligue diretamente para o controle.

No exemplo de cdigo a seguir, uma chamada de thread-safe implementada na T h r e a d P r o c S a f emtodo, que executado pelo thread de segundo plano. Se a TextBox do controle InvokeRequired retornatrue, o T h r e a d P r o c S a f emtodo cria uma instncia de S e t T e x t C a l l b a c k e passa que para o formulrio Invoke mtodo. Isso faz com que oS e t T e x tmtodo a ser chamado no thread que criou o TextBox controle e neste contexto do thread a Text propriedade definida diretamente. VB 'T h i se v e n th a n d l e rc r e a t e sat h r e a dt h a tc a l l sa 'W i n d o w sF o r m sc o n t r o li nat h r e a d s a f ew a y . P r i v a t eS u bs e t T e x t S a f e B t n _ C l i c k (_ B y V a ls e n d e rA sO b j e c t ,_ B y V a leA sE v e n t A r g s )H a n d l e ss e t T e x t S a f e B t n . C l i c k M e . d e m o T h r e a d=N e wT h r e a d (_ N e wT h r e a d S t a r t ( A d d r e s s O fM e . T h r e a d P r o c S a f e ) ) M e . d e m o T h r e a d . S t a r t ( ) E n dS u b

'T h i sm e t h o di se x e c u t e do nt h ew o r k e rt h r e a da n dm a k e s 'at h r e a d s a f ec a l lo nt h eT e x t B o xc o n t r o l . P r i v a t eS u bT h r e a d P r o c S a f e ( ) M e . S e t T e x t ( " T h i st e x tw a ss e ts a f e l y . " ) E n dS u b

C# / /T h i se v e n th a n d l e rc r e a t e sat h r e a dt h a tc a l l sa / /W i n d o w sF o r m sc o n t r o li nat h r e a d s a f ew a y . p r i v a t ev o i ds e t T e x t S a f e B t n _ C l i c k ( o b j e c ts e n d e r , E v e n t A r g se ) { t h i s . d e m o T h r e a d=

n e wT h r e a d ( n e wT h r e a d S t a r t ( t h i s . T h r e a d P r o c S a f e ) ) ; t h i s . d e m o T h r e a d . S t a r t ( ) ; } / /T h i sm e t h o di se x e c u t e do nt h ew o r k e rt h r e a da n dm a k e s / /at h r e a d s a f ec a l lo nt h eT e x t B o xc o n t r o l . p r i v a t ev o i dT h r e a d P r o c S a f e ( ) { t h i s . S e t T e x t ( " T h i st e x tw a ss e ts a f e l y . " ) ; }

C++ / /T h i se v e n th a n d l e rc r e a t e sat h r e a dt h a tc a l l sa / /W i n d o w sF o r m sc o n t r o li nat h r e a d s a f ew a y . p r i v a t e : v o i ds e t T e x t S a f e B t n _ C l i c k ( O b j e c t ^s e n d e r ,E v e n t A r g s ^e ) { t h i s > d e m o T h r e a d= g c n e wT h r e a d ( g c n e wT h r e a d S t a r t ( t h i s , & F o r m 1 : : T h r e a d P r o c S a f e ) ) ; t h i s > d e m o T h r e a d > S t a r t ( ) ; } / /T h i sm e t h o di se x e c u t e do nt h ew o r k e rt h r e a da n dm a k e s / /at h r e a d s a f ec a l lo nt h eT e x t B o xc o n t r o l . p r i v a t e : v o i dT h r e a d P r o c S a f e ( ) { t h i s > S e t T e x t ( " T h i st e x tw a ss e ts a f e l y . " ) ; }

VB 'T h i sm e t h o dd e m o n s t r a t e sap a t t e r nf o rm a k i n gt h r e a d s a f e 'c a l l so naW i n d o w sF o r m sc o n t r o l . ' 'I ft h ec a l l i n gt h r e a di sd i f f e r e n tf r o mt h et h r e a dt h a t 'c r e a t e dt h eT e x t B o xc o n t r o l ,t h i sm e t h o dc r e a t e sa 'S e t T e x t C a l l b a c ka n dc a l l si t s e l fa s y n c h r o n o u s l yu s i n gt h e 'I n v o k em e t h o d . ' 'I ft h ec a l l i n gt h r e a di st h es a m ea st h et h r e a dt h a tc r e a t e d 't h eT e x t B o xc o n t r o l ,t h eT e x tp r o p e r t yi ss e td i r e c t l y . P r i v a t eS u bS e t T e x t ( B y V a l[ t e x t ]A sS t r i n g ) 'I n v o k e R e q u i r e dr e q u i r e dc o m p a r e st h et h r e a dI Do ft h e 'c a l l i n gt h r e a dt ot h et h r e a dI Do ft h ec r e a t i n gt h r e a d . 'I ft h e s et h r e a d sa r ed i f f e r e n t ,i tr e t u r n st r u e . I fM e . t e x t B o x 1 . I n v o k e R e q u i r e dT h e n D i mdA sN e wS e t T e x t C a l l b a c k ( A d d r e s s O fS e t T e x t ) M e . I n v o k e ( d ,N e wO b j e c t ( ){ [ t e x t ] } ) E l s e M e . t e x t B o x 1 . T e x t=[ t e x t ] E n dI f E n dS u b

C# / /T h i sm e t h o dd e m o n s t r a t e sap a t t e r nf o rm a k i n gt h r e a d s a f e / /c a l l so naW i n d o w sF o r m sc o n t r o l . / / / /I ft h ec a l l i n gt h r e a di sd i f f e r e n tf r o mt h et h r e a dt h a t / /c r e a t e dt h eT e x t B o xc o n t r o l ,t h i sm e t h o dc r e a t e sa / /S e t T e x t C a l l b a c ka n dc a l l si t s e l fa s y n c h r o n o u s l yu s i n gt h e / /I n v o k em e t h o d . / /

/ /I ft h ec a l l i n gt h r e a di st h es a m ea st h et h r e a dt h a tc r e a t e d / /t h eT e x t B o xc o n t r o l ,t h eT e x tp r o p e r t yi ss e td i r e c t l y . p r i v a t ev o i dS e t T e x t ( s t r i n gt e x t ) { / /I n v o k e R e q u i r e dr e q u i r e dc o m p a r e st h et h r e a dI Do ft h e / /c a l l i n gt h r e a dt ot h et h r e a dI Do ft h ec r e a t i n gt h r e a d . / /I ft h e s et h r e a d sa r ed i f f e r e n t ,i tr e t u r n st r u e . i f( t h i s . t e x t B o x 1 . I n v o k e R e q u i r e d ) { S e t T e x t C a l l b a c kd=n e wS e t T e x t C a l l b a c k ( S e t T e x t ) ; t h i s . I n v o k e ( d ,n e wo b j e c t [ ]{t e x t} ) ; } e l s e { t h i s . t e x t B o x 1 . T e x t=t e x t ; } }

C++ / /T h i sm e t h o dd e m o n s t r a t e sap a t t e r nf o rm a k i n gt h r e a d s a f e / /c a l l so naW i n d o w sF o r m sc o n t r o l . / / / /I ft h ec a l l i n gt h r e a di sd i f f e r e n tf r o mt h et h r e a dt h a t / /c r e a t e dt h eT e x t B o xc o n t r o l ,t h i sm e t h o dc r e a t e sa / /S e t T e x t D e l e g a t ea n dc a l l si t s e l fa s y n c h r o n o u s l yu s i n gt h e / /I n v o k em e t h o d . / / / /I ft h ec a l l i n gt h r e a di st h es a m ea st h et h r e a dt h a tc r e a t e d / /t h eT e x t B o xc o n t r o l ,t h eT e x tp r o p e r t yi ss e td i r e c t l y . p r i v a t e : v o i dS e t T e x t ( S t r i n g ^t e x t ) { / /I n v o k e R e q u i r e dr e q u i r e dc o m p a r e st h et h r e a dI Do ft h e

/ /c a l l i n gt h r e a dt ot h et h r e a dI Do ft h ec r e a t i n gt h r e a d . / /I ft h e s et h r e a d sa r ed i f f e r e n t ,i tr e t u r n st r u e . i f( t h i s > t e x t B o x 1 > I n v o k e R e q u i r e d ) { S e t T e x t D e l e g a t e ^d= g c n e wS e t T e x t D e l e g a t e ( t h i s ,& F o r m 1 : : S e t T e x t ) ; t h i s > I n v o k e ( d ,g c n e wa r r a y < O b j e c t ^ >{t e x t} ) ; } e l s e { t h i s > t e x t B o x 1 > T e x t=t e x t ; } }

Fazer chamadas de Thread-Safe usando BackgroundWorker


A melhor maneira usar multithreading em seu aplicativo de implementar a BackgroundWorker componente. O BackgroundWorkercomponente usa um modelo orientada a eventos para multithreading. O segmento de plano de fundo executado sua DoWork manipulador de eventos e o segmento que cria a execuo de controles deProgressChanged e RunWorkerCompleted manipuladores de eventos.Voc pode ligar controles a partir de seu ProgressChanged eRunWorkerCompleted manipuladores de eventos.

Para fazer chamadas de thread-safe usando BackgroundWorker


1. Crie um mtodo para fazer o trabalho ser feito no thread de segundo plano. No chame controles criados pelo thread principal neste mtodo. 2. Crie um mtodo para relatar os resultados do seu trabalho de plano de fundo, depois de terminar. Voc pode chamar os controles criados pelo thread principal neste mtodo. 3. Vincular o mtodo criado na etapa 1 para o DoWork o evento de uma instncia de BackgroundWorkere vincular o mtodo criado na etapa 2 na mesma instncia RunWorkerCompleted evento. 4. Para iniciar o segmento de plano de fundo, chame oRunWorkerAsync mtodo da BackgroundWorker instncia.

No exemplo de cdigo a seguir, o DoWork usa o manipulador de eventos Sleep para simular o trabalho que leva algum tempo. Ele no chama o formulrio TextBox controle. O TextBox do controle Textpropriedade definida diretamente na RunWorkerCompletedmanipulador de eventos. VB 'T h i sB a c k g r o u n d W o r k e ri su s e dt od e m o n s t r a t et h e 'p r e f e r r e dw a yo fp e r f o r m i n ga s y n c h r o n o u so p e r a t i o n s . P r i v a t eW i t h E v e n t sb a c k g r o u n d W o r k e r 1A sB a c k g r o u n d W o r k e r

C# / /T h i sB a c k g r o u n d W o r k e ri su s e dt od e m o n s t r a t et h e / /p r e f e r r e dw a yo fp e r f o r m i n ga s y n c h r o n o u so p e r a t i o n s . p r i v a t eB a c k g r o u n d W o r k e rb a c k g r o u n d W o r k e r 1 ;

C++ / /T h i sB a c k g r o u n d W o r k e ri su s e dt od e m o n s t r a t et h e / /p r e f e r r e dw a yo fp e r f o r m i n ga s y n c h r o n o u so p e r a t i o n s . p r i v a t e : B a c k g r o u n d W o r k e r ^b a c k g r o u n d W o r k e r 1 ;

VB 'T h i se v e n th a n d l e rs t a r t st h ef o r m ' s 'B a c k g r o u n d W o r k e rb yc a l l i n gR u n W o r k e r A s y n c . ' 'T h eT e x tp r o p e r t yo ft h eT e x t B o xc o n t r o li ss e t 'w h e nt h eB a c k g r o u n d W o r k e rr a i s e st h eR u n W o r k e r C o m p l e t e d 'e v e n t .

P r i v a t eS u bs e t T e x t B a c k g r o u n d W o r k e r B t n _ C l i c k (_ B y V a ls e n d e rA sO b j e c t ,_ B y V a leA sE v e n t A r g s )H a n d l e ss e t T e x t B a c k g r o u n d W o r k e r B t n . C l i c k M e . b a c k g r o u n d W o r k e r 1 . R u n W o r k e r A s y n c ( ) E n dS u b

'T h i se v e n th a n d l e rs e t st h eT e x tp r o p e r t yo ft h eT e x t B o x 'c o n t r o l .I ti sc a l l e do nt h et h r e a dt h a tc r e a t e dt h e 'T e x t B o xc o n t r o l ,s ot h ec a l li st h r e a d s a f e . ' 'B a c k g r o u n d W o r k e ri st h ep r e f e r r e dw a yt op e r f o r ma s y n c h r o n o u s 'o p e r a t i o n s . P r i v a t eS u bb a c k g r o u n d W o r k e r 1 _ R u n W o r k e r C o m p l e t e d (_ B y V a ls e n d e rA sO b j e c t ,_ B y V a leA sR u n W o r k e r C o m p l e t e d E v e n t A r g s )_ H a n d l e sb a c k g r o u n d W o r k e r 1 . R u n W o r k e r C o m p l e t e d M e . t e x t B o x 1 . T e x t=_ " T h i st e x tw a ss e ts a f e l yb yB a c k g r o u n d W o r k e r . " E n dS u b

C# / /T h i se v e n th a n d l e rs t a r t st h ef o r m ' s / /B a c k g r o u n d W o r k e rb yc a l l i n gR u n W o r k e r A s y n c . / / / /T h eT e x tp r o p e r t yo ft h eT e x t B o xc o n t r o li ss e t / /w h e nt h eB a c k g r o u n d W o r k e rr a i s e st h eR u n W o r k e r C o m p l e t e d / /e v e n t . p r i v a t ev o i ds e t T e x t B a c k g r o u n d W o r k e r B t n _ C l i c k ( o b j e c ts e n d e r , E v e n t A r g se ) { t h i s . b a c k g r o u n d W o r k e r 1 . R u n W o r k e r A s y n c ( ) ; }

/ /T h i se v e n th a n d l e rs e t st h eT e x tp r o p e r t yo ft h eT e x t B o x / /c o n t r o l .I ti sc a l l e do nt h et h r e a dt h a tc r e a t e dt h e / /T e x t B o xc o n t r o l ,s ot h ec a l li st h r e a d s a f e . / / / /B a c k g r o u n d W o r k e ri st h ep r e f e r r e dw a yt op e r f o r ma s y n c h r o n o u s / /o p e r a t i o n s . p r i v a t ev o i db a c k g r o u n d W o r k e r 1 _ R u n W o r k e r C o m p l e t e d ( o b j e c ts e n d e r , R u n W o r k e r C o m p l e t e d E v e n t A r g se ) { t h i s . t e x t B o x 1 . T e x t= " T h i st e x tw a ss e ts a f e l yb yB a c k g r o u n d W o r k e r . " ; }

C++ / /T h i se v e n th a n d l e rs t a r t st h ef o r m ' s / /B a c k g r o u n d W o r k e rb yc a l l i n gR u n W o r k e r A s y n c . / / / /T h eT e x tp r o p e r t yo ft h eT e x t B o xc o n t r o li ss e t / /w h e nt h eB a c k g r o u n d W o r k e rr a i s e st h eR u n W o r k e r C o m p l e t e d / /e v e n t . p r i v a t e : v o i ds e t T e x t B a c k g r o u n d W o r k e r B t n _ C l i c k ( O b j e c t ^s e n d e r ,E v e n t A r g s ^e ) { t h i s > b a c k g r o u n d W o r k e r 1 > R u n W o r k e r A s y n c ( ) ; } / /T h i se v e n th a n d l e rs e t st h eT e x tp r o p e r t yo ft h eT e x t B o x / /c o n t r o l .I ti sc a l l e do nt h et h r e a dt h a tc r e a t e dt h e / /T e x t B o xc o n t r o l ,s ot h ec a l li st h r e a d s a f e . / / / /B a c k g r o u n d W o r k e ri st h ep r e f e r r e dw a yt op e r f o r ma s y n c h r o n o u s / /o p e r a t i o n s .

p r i v a t e : v o i db a c k g r o u n d W o r k e r 1 _ R u n W o r k e r C o m p l e t e d ( O b j e c t ^s e n d e r , R u n W o r k e r C o m p l e t e d E v e n t A r g s ^e ) { t h i s > t e x t B o x 1 > T e x t= " T h i st e x tw a ss e ts a f e l yb yB a c k g r o u n d W o r k e r . " ; }

Voc tambm pode relatar o andamento de uma tarefa de plano de fundo usando o ProgressChanged evento. Para obter um exemplo que incorpora desse evento, consulte BackgroundWorker.

Exemplo
O exemplo de cdigo a seguir um aplicativo Windows Forms completo que consiste em um formulrio com trs botes e uma caixa de texto. O primeiro boto demonstra o acesso de thread cruzado no seguro, o segundo boto demonstra o acesso seguro usando Invoke, e o terceiro boto demonstra o acesso seguro usando BackgroundWorker.

Observao Para obter instrues sobre como executar o exemplo, consulteComo compilar e executar um exemplo de cdigo dos Windows Forms concludo usando Visual Studio. Este exemplo requer referncias aos assemblies System. Drawing e System.Windows.Forms.
C# C++ VB

u s i n gS y s t e m ; u s i n gS y s t e m . C o m p o n e n t M o d e l ; u s i n gS y s t e m . T h r e a d i n g ; u s i n gS y s t e m . W i n d o w s . F o r m s ;

n a m e s p a c eC r o s s T h r e a d D e m o { p u b l i cc l a s sF o r m 1:F o r m { / /T h i sd e l e g a t ee n a b l e sa s y n c h r o n o u sc a l l sf o rs e t t i n g / /t h et e x tp r o p e r t yo naT e x t B o xc o n t r o l . d e l e g a t ev o i dS e t T e x t C a l l b a c k ( s t r i n gt e x t ) ; / /T h i st h r e a di su s e dt od e m o n s t r a t eb o t ht h r e a d s a f ea n d / /u n s a f ew a y st oc a l laW i n d o w sF o r m sc o n t r o l . p r i v a t eT h r e a dd e m o T h r e a d=n u l l ; / /T h i sB a c k g r o u n d W o r k e ri su s e dt od e m o n s t r a t et h e / /p r e f e r r e dw a yo fp e r f o r m i n ga s y n c h r o n o u so p e r a t i o n s . p r i v a t eB a c k g r o u n d W o r k e rb a c k g r o u n d W o r k e r 1 ; p r i v a t eT e x t B o xt e x t B o x 1 ; p r i v a t eB u t t o ns e t T e x t U n s a f e B t n ; p r i v a t eB u t t o ns e t T e x t S a f e B t n ; p r i v a t eB u t t o ns e t T e x t B a c k g r o u n d W o r k e r B t n ; p r i v a t eS y s t e m . C o m p o n e n t M o d e l . I C o n t a i n e rc o m p o n e n t s=n u l l ; p u b l i cF o r m 1 ( ) { I n i t i a l i z e C o m p o n e n t ( ) ; } p r o t e c t e do v e r r i d ev o i dD i s p o s e ( b o o ld i s p o s i n g ) { i f( d i s p o s i n g& &( c o m p o n e n t s! =n u l l ) ) { c o m p o n e n t s . D i s p o s e ( ) ; } b a s e . D i s p o s e ( d i s p o s i n g ) ; } / /T h i se v e n th a n d l e rc r e a t e sat h r e a dt h a tc a l l sa / /W i n d o w sF o r m sc o n t r o li na nu n s a f ew a y .

p r i v a t ev o i ds e t T e x t U n s a f e B t n _ C l i c k ( o b j e c ts e n d e r , E v e n t A r g se ) { t h i s . d e m o T h r e a d= n e wT h r e a d ( n e wT h r e a d S t a r t ( t h i s . T h r e a d P r o c U n s a f e ) ) ; t h i s . d e m o T h r e a d . S t a r t ( ) ; } / /T h i sm e t h o di se x e c u t e do nt h ew o r k e rt h r e a da n dm a k e s / /a nu n s a f ec a l lo nt h eT e x t B o xc o n t r o l . p r i v a t ev o i dT h r e a d P r o c U n s a f e ( ) { t h i s . t e x t B o x 1 . T e x t=" T h i st e x tw a ss e tu n s a f e l y . " ; } / /T h i se v e n th a n d l e rc r e a t e sat h r e a dt h a tc a l l sa / /W i n d o w sF o r m sc o n t r o li nat h r e a d s a f ew a y . p r i v a t ev o i ds e t T e x t S a f e B t n _ C l i c k ( o b j e c ts e n d e r , E v e n t A r g se ) { t h i s . d e m o T h r e a d= n e wT h r e a d ( n e wT h r e a d S t a r t ( t h i s . T h r e a d P r o c S a f e ) ) ; t h i s . d e m o T h r e a d . S t a r t ( ) ; } / /T h i sm e t h o di se x e c u t e do nt h ew o r k e rt h r e a da n dm a k e s / /at h r e a d s a f ec a l lo nt h eT e x t B o xc o n t r o l . p r i v a t ev o i dT h r e a d P r o c S a f e ( ) { t h i s . S e t T e x t ( " T h i st e x tw a ss e ts a f e l y . " ) ; } / /T h i sm e t h o dd e m o n s t r a t e sap a t t e r nf o rm a k i n gt h r e a d s a f e / /c a l l so naW i n d o w sF o r m sc o n t r o l . / /

/ /I ft h ec a l l i n gt h r e a di sd i f f e r e n tf r o mt h et h r e a dt h a t / /c r e a t e dt h eT e x t B o xc o n t r o l ,t h i sm e t h o dc r e a t e sa / /S e t T e x t C a l l b a c ka n dc a l l si t s e l fa s y n c h r o n o u s l yu s i n gt h e / /I n v o k em e t h o d . / / / /I ft h ec a l l i n gt h r e a di st h es a m ea st h et h r e a dt h a tc r e a t e d / /t h eT e x t B o xc o n t r o l ,t h eT e x tp r o p e r t yi ss e td i r e c t l y . p r i v a t ev o i dS e t T e x t ( s t r i n gt e x t ) { / /I n v o k e R e q u i r e dr e q u i r e dc o m p a r e st h et h r e a dI Do ft h e / /c a l l i n gt h r e a dt ot h et h r e a dI Do ft h ec r e a t i n gt h r e a d . / /I ft h e s et h r e a d sa r ed i f f e r e n t ,i tr e t u r n st r u e . i f( t h i s . t e x t B o x 1 . I n v o k e R e q u i r e d ) { S e t T e x t C a l l b a c kd=n e wS e t T e x t C a l l b a c k ( S e t T e x t ) ; t h i s . I n v o k e ( d ,n e wo b j e c t [ ]{t e x t} ) ; } e l s e { t h i s . t e x t B o x 1 . T e x t=t e x t ; } } / /T h i se v e n th a n d l e rs t a r t st h ef o r m ' s / /B a c k g r o u n d W o r k e rb yc a l l i n gR u n W o r k e r A s y n c . / / / /T h eT e x tp r o p e r t yo ft h eT e x t B o xc o n t r o li ss e t / /w h e nt h eB a c k g r o u n d W o r k e rr a i s e st h eR u n W o r k e r C o m p l e t e d / /e v e n t . p r i v a t ev o i ds e t T e x t B a c k g r o u n d W o r k e r B t n _ C l i c k ( o b j e c ts e n d e r , E v e n t A r g se ) { t h i s . b a c k g r o u n d W o r k e r 1 . R u n W o r k e r A s y n c ( ) ; } / /T h i se v e n th a n d l e rs e t st h eT e x tp r o p e r t yo ft h eT e x t B o x / /c o n t r o l .I ti sc a l l e do nt h et h r e a dt h a tc r e a t e dt h e

/ /T e x t B o xc o n t r o l ,s ot h ec a l li st h r e a d s a f e . / / / /B a c k g r o u n d W o r k e ri st h ep r e f e r r e dw a yt op e r f o r ma s y n c h r o n o u s / /o p e r a t i o n s . p r i v a t ev o i db a c k g r o u n d W o r k e r 1 _ R u n W o r k e r C o m p l e t e d ( o b j e c ts e n d e r , R u n W o r k e r C o m p l e t e d E v e n t A r g se ) { t h i s . t e x t B o x 1 . T e x t= " T h i st e x tw a ss e ts a f e l yb yB a c k g r o u n d W o r k e r . " ; } # r e g i o nW i n d o w sF o r mD e s i g n e rg e n e r a t e dc o d e p r i v a t ev o i dI n i t i a l i z e C o m p o n e n t ( ) { t h i s . t e x t B o x 1=n e wS y s t e m . W i n d o w s . F o r m s . T e x t B o x ( ) ; t h i s . s e t T e x t U n s a f e B t n=n e wS y s t e m . W i n d o w s . F o r m s . B u t t o n ( ) ; t h i s . s e t T e x t S a f e B t n=n e wS y s t e m . W i n d o w s . F o r m s . B u t t o n ( ) ; t h i s . s e t T e x t B a c k g r o u n d W o r k e r B t n=n e wS y s t e m . W i n d o w s . F o r m s . B u t t o n ( ) ; t h i s . b a c k g r o u n d W o r k e r 1=n e wS y s t e m . C o m p o n e n t M o d e l . B a c k g r o u n d W o r k e r ( ) ; t h i s . S u s p e n d L a y o u t ( ) ; / / / /t e x t B o x 1 / / t h i s . t e x t B o x 1 . L o c a t i o n=n e wS y s t e m . D r a w i n g . P o i n t ( 1 2 ,1 2 ) ; t h i s . t e x t B o x 1 . N a m e=" t e x t B o x 1 " ; t h i s . t e x t B o x 1 . S i z e=n e wS y s t e m . D r a w i n g . S i z e ( 2 4 0 ,2 0 ) ; t h i s . t e x t B o x 1 . T a b I n d e x=0 ; / / / /s e t T e x t U n s a f e B t n / / t h i s . s e t T e x t U n s a f e B t n . L o c a t i o n=n e wS y s t e m . D r a w i n g . P o i n t ( 1 5 ,5 5 ) ; t h i s . s e t T e x t U n s a f e B t n . N a m e=" s e t T e x t U n s a f e B t n " ; t h i s . s e t T e x t U n s a f e B t n . T a b I n d e x=1 ; t h i s . s e t T e x t U n s a f e B t n . T e x t=" U n s a f eC a l l " ; t h i s . s e t T e x t U n s a f e B t n . C l i c k+ =n e wS y s t e m . E v e n t H a n d l e r ( t h i s . s e t T e x t U n s a f e B t n _ C l i c k ) ; / /

/ /s e t T e x t S a f e B t n / / t h i s . s e t T e x t S a f e B t n . L o c a t i o n=n e wS y s t e m . D r a w i n g . P o i n t ( 9 6 ,5 5 ) ; t h i s . s e t T e x t S a f e B t n . N a m e=" s e t T e x t S a f e B t n " ; t h i s . s e t T e x t S a f e B t n . T a b I n d e x=2 ; t h i s . s e t T e x t S a f e B t n . T e x t=" S a f eC a l l " ; t h i s . s e t T e x t S a f e B t n . C l i c k+ =n e wS y s t e m . E v e n t H a n d l e r ( t h i s . s e t T e x t S a f e B t n _ C l i c k ) ; / / / /s e t T e x t B a c k g r o u n d W o r k e r B t n / / t h i s . s e t T e x t B a c k g r o u n d W o r k e r B t n . L o c a t i o n=n e wS y s t e m . D r a w i n g . P o i n t ( 1 7 7 ,5 5 ) ; t h i s . s e t T e x t B a c k g r o u n d W o r k e r B t n . N a m e=" s e t T e x t B a c k g r o u n d W o r k e r B t n " ; t h i s . s e t T e x t B a c k g r o u n d W o r k e r B t n . T a b I n d e x=3 ; t h i s . s e t T e x t B a c k g r o u n d W o r k e r B t n . T e x t=" S a f eB WC a l l " ; t h i s . s e t T e x t B a c k g r o u n d W o r k e r B t n . C l i c k+ =n e wS y s t e m . E v e n t H a n d l e r ( t h i s . s e t T e x t B a c k g r o u n d W o r k e r B t n _ C l i c k ) ; / / / /b a c k g r o u n d W o r k e r 1 / / t h i s . b a c k g r o u n d W o r k e r 1 . R u n W o r k e r C o m p l e t e d+ =n e wS y s t e m . C o m p o n e n t M o d e l . R u n W o r k e r C o m p l e t e d E v e n t H a n d l e r ( t h i s . b a c k g r o / / / /F o r m 1 / / t h i s . C l i e n t S i z e=n e wS y s t e m . D r a w i n g . S i z e ( 2 6 8 ,9 6 ) ; t h i s . C o n t r o l s . A d d ( t h i s . s e t T e x t B a c k g r o u n d W o r k e r B t n ) ; t h i s . C o n t r o l s . A d d ( t h i s . s e t T e x t S a f e B t n ) ; t h i s . C o n t r o l s . A d d ( t h i s . s e t T e x t U n s a f e B t n ) ; t h i s . C o n t r o l s . A d d ( t h i s . t e x t B o x 1 ) ; t h i s . N a m e=" F o r m 1 " ; t h i s . T e x t=" F o r m 1 " ; t h i s . R e s u m e L a y o u t ( f a l s e ) ; t h i s . P e r f o r m L a y o u t ( ) ; } # e n d r e g i o n

[ S T A T h r e a d ] s t a t i cv o i dM a i n ( )

{ A p p l i c a t i o n . E n a b l e V i s u a l S t y l e s ( ) ; A p p l i c a t i o n . R u n ( n e wF o r m 1 ( ) ) ; } } }

Quando voc executar o aplicativo e clique no No seguro chamarboto, voc imediatamente ver "Gravadas pelo thread principal" na caixa de texto. Dois segundos mais tarde, quando a chamada no segura tentada, o depurador Visual Studio indica que ocorreu uma exceo. O depurador pra na linha de no thread de plano de fundo que tentou gravar diretamente para a caixa de texto. Voc precisar reiniciar o aplicativo para testar os outros dois botes. Quando voc clica noSeguro chamar boto "Gravada pelo thread principal" exibida na caixa de texto. Dois segundos mais tarde, a caixa de texto estiver definida como "Gravadas pelo segmento de plano de fundo (Invoke)", que indica que o Invoke o mtodo foi chamado. Quando voc clica o Chamar de BW seguro boto "Gravada pelo thread principal" exibida na caixa de texto. Dois segundos mais tarde, a caixa de texto definida como "Gravadas pelo thread principal", aps a concluso do thread de segundo plano que indica que o manipulador para oRunWorkerCompleted o evento de BackgroundWorker foi chamado.