Cómo Realizar llamadas seguras para subprocesos en controles de formularios Windows Forms

download Cómo Realizar llamadas seguras para subprocesos en controles de formularios Windows Forms

of 8

Transcript of Cómo Realizar llamadas seguras para subprocesos en controles de formularios Windows Forms

  • 7/31/2019 Cmo Realizar llamadas seguras para subprocesos en controles de formularios Windows Forms

    1/8

    Cmo Realizar llamadas seguras parasubprocesos en controles de formulariosWindows FormsVisual Studio 2010Otras versiones

    Personas que lo han encontrado til: 0 de 1 - Valorar este tema

    Si utiliza multithreading para mejorar el rendimiento de las aplicaciones de Windows Forms, debeasegurarse de realizar llamadas a los controles de forma segura.

    El acceso a los controles de formularios Windows Forms no es inherentemente seguro para lossubprocesos. Si dos o ms subprocesos manipulan el estado de un control, es posible obligar al control apasar a un estado incoherente. Se pueden dar otros errores relacionados con los subprocesos, comocondiciones de carrera e interbloqueos. Es importante asegurarse de que el acceso a los controles serealice de manera segura para los subprocesos.

    No es seguro llamar a un control desde un subproceso distinto del que cre el control sin utilizar elmtodo Invoke. A continuacin figura un ejemplo de una llamada que no es segura para los subprocesos.

    C#C++VB

    // This event handler creates a thread that calls a// Windows Forms control in an unsafe way.privatevoid setTextUnsafeBtn_Click(

    object sender,EventArgs e)

    {

    this.demoThread =new Thread(new ThreadStart(this.ThreadProcUnsafe));

    this.demoThread.Start();}

    // This method is executed on the worker thread and makes// an unsafe call on the TextBox control.privatevoid ThreadProcUnsafe(){

    this.textBox1.Text = "This text was set unsafely.";}

    .NET Framework ayuda a detectar cundo el acceso a los controles se produce de una manera no segurapara los subprocesos. Cuando se est ejecutando la aplicacin en un depurador y un subproceso distintodel que cre un control intenta llamar a ese control, el depurador inicia unaexcepcin InvalidOperationException con el mensaje: "Se tuvo acceso al control nombre del controldesdeun subproceso distinto a aquel en que lo cre".

    Esta excepcin aparece de forma fiable durante la depuracin y, en algunas circunstancias, en tiempo deejecucin. Esta excepcin puede aparecer cuando se depuran aplicaciones escritas con una versin de.NET Framework anterior a .NET Framework versin 2.0. Cuando surja este problema, se recomiendacorregirlo, si bien se puede deshabilitarlo estableciendo el valor de la

    propiedad CheckForIllegalCrossThreadCalls enfalse. Esto hace que el control se ejecute de la mismamanera que si se ejecutara en Visual Studio .NET 2003 y .NET Framework 1.1.

    Nota

    http://msdn.microsoft.com/es-es/library/ms171728.aspx#feedbackhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.invoke.aspxhttp://msdn.microsoft.com/es-es/library/system.invalidoperationexception.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.checkforillegalcrossthreadcalls.aspxhttp://msdn.microsoft.com/es-es/library/ms171728.aspx#feedbackhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.invoke.aspxhttp://msdn.microsoft.com/es-es/library/system.invalidoperationexception.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.checkforillegalcrossthreadcalls.aspx
  • 7/31/2019 Cmo Realizar llamadas seguras para subprocesos en controles de formularios Windows Forms

    2/8

    Si usa controles ActiveX en un formulario, puede que se inicie la excepcinInvalidOperationException entre subproce

    controles ActiveX no admiten multithreading. Para obtener ms informacin sobre cmo utilizar los controles ActiveX

    aplicaciones no administradas. Si utiliza Visual Studio, puede evitar esta excepcin deshabilitando el proceso de hospe

    Realizar llamadas seguras para subprocesos a controles deWindows Forms

    Para realizar una llamada segura para subprocesos a un control de Windows Forms

    1. Consulte la propiedad InvokeRequired del control.2. Si la propiedad InvokeRequired devuelve true, llame a Invoke con un delegado que realice la

    llamada real al control.

    3. Si la propiedad InvokeRequired devuelve false, llame directamente al control.

    En el siguiente ejemplo de cdigo, se implementa una llamada segura para subprocesos en elmtodo ThreadProcSafe, que el subproceso en segundo plano ejecuta. Si la

    propiedad InvokeRequired del controlTextBoxdevuelve true, el mtodo ThreadProcSafe crea unainstancia de SetTextCallback y la pasa al mtodo Invoke del formulario. Esto hace que se llame almtodo SetText en el subproceso que ha creado el controlTextBox, y en este contexto de subproceso se

    establece directamente la propiedadText.

    C#C++VB// This event handler creates a thread that calls a // Windows Forms control in a thread-safeway.privatevoid setTextSafeBtn_Click(

    object sender,EventArgs e)

    {this.demoThread =

    new Thread(new ThreadStart(this.ThreadProcSafe));

    this.demoThread.Start();}

    // This method is executed on the worker thread and makes// a thread-safe call on theTextBox control.privatevoid ThreadProcSafe()

    {this.SetText("This text was set safely.");

    }

    C#C++VB// This method demonstrates a pattern for making thread-safe// calls on a Windows Forms control. //// Ifthe calling thread is different from the thread that// created the TextBox control, this method creates a//SetTextCallback and calls itself asynchronously using the// Invoke method.//// If the calling thread is thesame as the thread that created// the TextBox control, the Text property is set directly. privatevoidSetText(string text)

    {// InvokeRequired required compares the thread ID of the// calling thread to

    the thread ID of the creating thread.// If these threads are different, it returns true.if(this.textBox1.InvokeRequired)

    {SetTextCallback d = new SetTextCallback(SetText);

    this.Invoke(d, newobject[] { text });}else{

    this.textBox1.Text = text;}

    http://msdn.microsoft.com/es-es/library/system.invalidoperationexception.aspxhttp://msdn.microsoft.com/es-es/library/system.invalidoperationexception.aspxhttp://msdn.microsoft.com/es-es/library/ms229610.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.invokerequired.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.invokerequired.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.invoke.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.invokerequired.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.invokerequired.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.textbox.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.textbox.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.invoke.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.textbox.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.text.aspxhttp://void%280%29/http://msdn.microsoft.com/es-es/library/system.invalidoperationexception.aspxhttp://msdn.microsoft.com/es-es/library/ms229610.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.invokerequired.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.invokerequired.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.invoke.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.invokerequired.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.invokerequired.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.textbox.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.invoke.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.textbox.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.text.aspx
  • 7/31/2019 Cmo Realizar llamadas seguras para subprocesos en controles de formularios Windows Forms

    3/8

    }

    Realizar llamadas seguras para subprocesos medianteBackgroundWorker

    La mejor manera de implementar el multithreading en la aplicacin es utilizar el

    componenteBackgroundWorker. El componenteBackgroundWorker utiliza un modelo orientado a eventospara el multithreading. El subproceso en segundo plano ejecuta el controlador de eventosDoWork y elsubproceso que crea los controles llama a los controladores deeventos ProgressChanged y RunWorkerCompleted. Puede llamar a los controles desde los controladoresde eventosRunWorkerCompleted y ProgressChanged.

    Para realizar llamadas seguras para subprocesos mediante BackgroundWorker

    1. Cree un mtodo para que las operaciones que desee realizar se lleven a cabo en el subproceso ensegundo plano. No llame a los controles creados por el subproceso principal en este mtodo.

    2. Cree un mtodo para notificar los resultados del trabajo en segundo plano una vezfinalizado. Puede llamar a los controles creados por el subproceso principal en este mtodo.

    3. Enlace el mtodo creado en el paso 1 al evento DoWork de una instancia de BackgroundWorker yenlace el mtodo creado en el paso 2 al evento RunWorkerCompleted de la misma instancia.4. Para iniciar el subproceso en segundo plano, llame al mtodo RunWorkerAsync de la instancia

    de BackgroundWorker.

    En el siguiente ejemplo de cdigo, el controlador de eventos DoWork utiliza Sleep para simular trabajo quetarda algn tiempo. No llama al controlTextBoxdel formulario. La propiedadText del controlTextBox seestablece directamente en el controlador de eventos RunWorkerCompleted.

    C#C++VB// This BackgroundWorker is used to demonstrate the // preferred way of performing asynchronousoperations.private BackgroundWorker backgroundWorker1;

    C#C++VB// This event handler starts the form's // BackgroundWorker by calling RunWorkerAsync.//// The Textproperty of the TextBox control is set// when the BackgroundWorker raises the RunWorkerCompleted//event.privatevoid setTextBackgroundWorkerBtn_Click(

    object sender,EventArgs e)

    {this.backgroundWorker1.RunWorkerAsync();

    }

    // This event handler sets the Text property of the TextBox// control. It is called on thethread that created the // TextBox control, so the call is thread-safe.//// BackgroundWorker is the preferredway to perform asynchronous// operations.privatevoid backgroundWorker1_RunWorkerCompleted(

    object sender,RunWorkerCompletedEventArgs e)

    {this.textBox1.Text =

    "This text was set safely by BackgroundWorker.";}

    Asimismo, se puede notificar el progreso de una tarea en segundo plano mediante elevento ProgressChanged. Para obtener un ejemplo que incluye ese evento, vea BackgroundWorker.

    http://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.dowork.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.dowork.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.progresschanged.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.runworkercompleted.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.runworkercompleted.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.runworkercompleted.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.progresschanged.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.dowork.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.runworkercompleted.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.runworkerasync.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.dowork.aspxhttp://msdn.microsoft.com/es-es/library/system.threading.thread.sleep.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.textbox.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.textbox.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.text.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.textbox.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.runworkercompleted.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.progresschanged.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.progresschanged.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://void%280%29/http://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.dowork.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.progresschanged.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.runworkercompleted.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.runworkercompleted.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.progresschanged.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.dowork.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.runworkercompleted.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.runworkerasync.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.dowork.aspxhttp://msdn.microsoft.com/es-es/library/system.threading.thread.sleep.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.textbox.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.control.text.aspxhttp://msdn.microsoft.com/es-es/library/system.windows.forms.textbox.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.runworkercompleted.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.progresschanged.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspx
  • 7/31/2019 Cmo Realizar llamadas seguras para subprocesos en controles de formularios Windows Forms

    4/8

    Ejemplo

    El siguiente ejemplo de cdigo es una aplicacin de Windows Forms completa que se compone de unformulario con tres botones y un cuadro de texto. El primer botn muestra el acceso no seguro entresubprocesos, el segundo botn muestra el acceso seguro mediante Invoke y el tercer botn muestra elacceso seguro medianteBackgroundWorker.

    NotaPara obtener instrucciones sobre cmo ejecutar el ejemplo, vea Cmo: Compilar y ejecutar un ejemplo de cdigo comlos ensamblados System.Drawing y System.Windows.Forms.

    C#C++VB

    using System;using System.ComponentModel;using System.Threading;using System.Windows.Forms;

    namespace CrossThreadDemo{

    publicclass Form1 : Form{

    // This delegate enables asynchronous calls for setting// the text property on a TextBox control.delegatevoid SetTextCallback(string text);

    // This thread is used to demonstrate both thread-safe and// unsafe ways to call a Windows Forms control.private Thread demoThread = null;

    // This BackgroundWorker is used to demonstrate the

    // preferred way of performing asynchronous operations.private BackgroundWorker backgroundWorker1;

    private TextBox textBox1;private Button setTextUnsafeBtn;private Button setTextSafeBtn;private Button setTextBackgroundWorkerBtn;

    private System.ComponentModel.IContainer components = null;

    public Form1(){

    InitializeComponent();}

    protectedoverridevoid Dispose(bool disposing){

    if(disposing && (components != null)){

    components.Dispose();}base.Dispose(disposing);

    }

    // This event handler creates a thread that calls a

    // Windows Forms control in an unsafe way.privatevoid setTextUnsafeBtn_Click(object sender,EventArgs e)

    {this.demoThread =

    http://msdn.microsoft.com/es-es/library/system.windows.forms.control.invoke.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://msdn.microsoft.com/es-es/library/bb129228.aspxhttp://void%280%29/http://msdn.microsoft.com/es-es/library/system.windows.forms.control.invoke.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://msdn.microsoft.com/es-es/library/bb129228.aspx
  • 7/31/2019 Cmo Realizar llamadas seguras para subprocesos en controles de formularios Windows Forms

    5/8

    new Thread(new ThreadStart(this.ThreadProcUnsafe));

    this.demoThread.Start();}

    // This method is executed on the worker thread and makes// an unsafe call on the TextBox control.privatevoid ThreadProcUnsafe(){

    this.textBox1.Text = "This text was set unsafely.";}

    // This event handler creates a thread that calls a// Windows Forms control in a thread-safe way.privatevoid setTextSafeBtn_Click(

    object sender,EventArgs e)

    {this.demoThread =

    new Thread(new ThreadStart(this.ThreadProcSafe));

    this.demoThread.Start();

    }

    // This method is executed on the worker thread and makes// a thread-safe call on the TextBox control.privatevoid ThreadProcSafe(){

    this.SetText("This text was set safely.");}

    // This method demonstrates a pattern for making thread-safe// calls on a Windows Forms control.//// If the calling thread is different from the thread that

    // created the TextBox control, this method creates a// SetTextCallback and calls itself asynchronously using the// Invoke method.//// If the calling thread is the same as the thread that created// the TextBox control, the Text property is set directly.

    privatevoid SetText(string text){

    // InvokeRequired required compares the thread ID of the// calling thread to the thread ID of the creating thread.// If these threads are different, it returns true.if(this.textBox1.InvokeRequired){

    SetTextCallback d = new SetTextCallback(SetText);this.Invoke(d, newobject[] { text });

    }else{

    this.textBox1.Text = text;}

    }

    // This event handler starts the form's// BackgroundWorker by calling RunWorkerAsync.

    //// The Text property of the TextBox control is set// when the BackgroundWorker raises the RunWorkerCompleted// event.privatevoid setTextBackgroundWorkerBtn_Click(

    object sender,

  • 7/31/2019 Cmo Realizar llamadas seguras para subprocesos en controles de formularios Windows Forms

    6/8

    EventArgs e){

    this.backgroundWorker1.RunWorkerAsync();}

    // This event handler sets the Text property of the TextBox// control. It is called on the thread that created the// TextBox control, so the call is thread-safe.//

    // BackgroundWorker is the preferred way to perform asynchronous// operations.

    privatevoid backgroundWorker1_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)

    {this.textBox1.Text =

    "This text was set safely by BackgroundWorker.";}

    #region Windows Form Designer generated code

    privatevoid InitializeComponent(){

    this.textBox1 = new System.Windows.Forms.TextBox();this.setTextUnsafeBtn = new System.Windows.Forms.Button();this.setTextSafeBtn = new System.Windows.Forms.Button();this.setTextBackgroundWorkerBtn = new System.Windows.Forms.Button();this.backgroundWorker1 = new

    System.ComponentModel.BackgroundWorker();this.SuspendLayout();//// textBox1//this.textBox1.Location = new System.Drawing.Point(12, 12);

    this.textBox1.Name = "textBox1";this.textBox1.Size = new System.Drawing.Size(240, 20);this.textBox1.TabIndex = 0;//// setTextUnsafeBtn//this.setTextUnsafeBtn.Location = new System.Drawing.Point(15, 55);this.setTextUnsafeBtn.Name = "setTextUnsafeBtn";this.setTextUnsafeBtn.TabIndex = 1;this.setTextUnsafeBtn.Text = "Unsafe Call";this.setTextUnsafeBtn.Click += new

    System.EventHandler(this.setTextUnsafeBtn_Click);//// setTextSafeBtn//this.setTextSafeBtn.Location = new System.Drawing.Point(96, 55);this.setTextSafeBtn.Name = "setTextSafeBtn";this.setTextSafeBtn.TabIndex = 2;this.setTextSafeBtn.Text = "Safe Call";this.setTextSafeBtn.Click += new

    System.EventHandler(this.setTextSafeBtn_Click);//// setTextBackgroundWorkerBtn//this.setTextBackgroundWorkerBtn.Location = new System.Drawing.Point(177,

    55); this.setTextBackgroundWorkerBtn.Name = "setTextBackgroundWorkerBtn";this.setTextBackgroundWorkerBtn.TabIndex = 3;this.setTextBackgroundWorkerBtn.Text = "Safe BW Call";this.setTextBackgroundWorkerBtn.Click += new

    System.EventHandler(this.setTextBackgroundWorkerBtn_Click);

  • 7/31/2019 Cmo Realizar llamadas seguras para subprocesos en controles de formularios Windows Forms

    7/8

    //// backgroundWorker1//this.backgroundWorker1.RunWorkerCompleted += new

    System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);

    //// Form1//

    this.ClientSize = new System.Drawing.Size(268, 96);this.Controls.Add(this.setTextBackgroundWorkerBtn);this.Controls.Add(this.setTextSafeBtn);this.Controls.Add(this.setTextUnsafeBtn);this.Controls.Add(this.textBox1);this.Name = "Form1";this.Text = "Form1";this.ResumeLayout(false);this.PerformLayout();

    }

    #endregion

    [STAThread]staticvoid Main(){

    Application.EnableVisualStyles();Application.Run(new Form1());

    }

    }}

    Cuando se ejecuta la aplicacin y se hace clic en el botn Unsafe Call (Llamada no segura), apareceinmediatamente el texto "Written by the main thread" (Escrito por el subproceso principal) en el cuadro detexto.Dos segundos despus, cuando se intenta realizar la llamada no segura, el depurador de VisualStudio indica que se ha producido una excepcin. El depurador se detiene en la lnea del subproceso ensegundo plano que intent escribir directamente en el cuadro de texto. Es preciso reiniciar la aplicacinpara probar los otros dos botones. Cuando se hace clic en el botn Safe Call (Llamada segura), apareceel texto "Written by the main thread" (Escrito por el subproceso principal) en el cuadro de texto. Dossegundos despus, el cuadro de texto se establece en "Written by the background thread (Invoke)"(Escrito por el subproceso en segundo plano (Invoke)), lo que indica que se llam almtodo Invoke. Cuando se hace clic en el botn Safe BW Call (Llamada segura a BW), aparece el texto"Written by the main thread" (Escrito por el subproceso principal) en el cuadro de texto. Dos segundos

    despus, el cuadro de texto se establece en "Written by the main thread after the background threadcompleted" (Escrito por el subproceso principal una vez completado el subproceso en segundo plano), loque indica que se llam al controlador del eventoRunWorkerCompleted de BackgroundWorker.

    Programacin eficaz

    PrecaucinCuando se utiliza el multithreading de cualquier ordenacin, el cdigo se puede exponer a errores graves y complejos.

    subprocesamiento administrado antes de implementar cualquier solucin que utilice multithreading.

    Vea tambin

    Tareas

    Cmo: Ejecutar una operacin en segundo planoCmo: Implementar un formulario que utiliza una operacin en segundo plano

    http://msdn.microsoft.com/es-es/library/system.windows.forms.control.invoke.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.runworkercompleted.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.runworkercompleted.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://msdn.microsoft.com/es-es/library/1c9txz50.aspxhttp://msdn.microsoft.com/es-es/library/hybbz6ke.aspxhttp://msdn.microsoft.com/es-es/library/waw3xexc.aspxhttp://void%280%29/http://void%280%29/http://msdn.microsoft.com/es-es/library/system.windows.forms.control.invoke.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.runworkercompleted.aspxhttp://msdn.microsoft.com/es-es/library/system.componentmodel.backgroundworker.aspxhttp://msdn.microsoft.com/es-es/library/1c9txz50.aspxhttp://msdn.microsoft.com/es-es/library/hybbz6ke.aspxhttp://msdn.microsoft.com/es-es/library/waw3xexc.aspx
  • 7/31/2019 Cmo Realizar llamadas seguras para subprocesos en controles de formularios Windows Forms

    8/8

    TOMADO:http://msdn.microsoft.com/es-es/library/ms171728.aspx

    DESDE GOOGLE.COM: control de llamadas con vb.net

    http://msdn.microsoft.com/es-es/library/ms171728.aspxhttp://msdn.microsoft.com/es-es/library/ms171728.aspxhttp://msdn.microsoft.com/es-es/library/ms171728.aspx