Beruflich Dokumente
Kultur Dokumente
.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.
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
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=
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 . / /
/ /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 ; } }
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 ;
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 . " ; }
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 ;
/ /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.