visual verbo tense studio snippet past pasado participle participio para fragmentos ejemplos codigos codigo code bite c# .net multithreading

c# - verbo - ¿Cómo ejecuto un simple bit de código en un nuevo hilo?



past participle of bite (15)

Aquí hay otra opción:

Task.Run(()=>{ //Here is a new thread });

Tengo un poco de código que necesito para ejecutar en un subproceso diferente al de la GUI ya que actualmente el formulario se congela mientras el código se ejecuta (alrededor de 10 segundos).

Supongamos que nunca he creado un nuevo hilo antes; ¿Qué es un ejemplo simple / básico de cómo hacer esto en C # y usar .NET Framework 2.0 o posterior?


Aquí, ¿cómo se pueden usar subprocesos con una barra de progreso? Es solo para entender cómo funcionan los subprocesos, en el formulario hay tres barras de progreso y 4 botones:

public partial class Form1 : Form { public Form1() { InitializeComponent(); } Thread t, t2, t3; private void Form1_Load(object sender, EventArgs e) { CheckForIllegalCrossThreadCalls = false; t = new Thread(birinicBar); //evry thread workes with a new progressBar t2 = new Thread(ikinciBar); t3 = new Thread(ucuncuBar); } public void birinicBar() //to make progressBar work { for (int i = 0; i < 100; i++) { progressBar1.Value++; Thread.Sleep(100); // this progressBar gonna work faster } } public void ikinciBar() { for (int i = 0; i < 100; i++) { progressBar2.Value++; Thread.Sleep(200); } } public void ucuncuBar() { for (int i = 0; i < 100; i++) { progressBar3.Value++; Thread.Sleep(300); } } private void button1_Click(object sender, EventArgs e) //that button to start the threads { t.Start(); t2.Start(); t3.Start(); } private void button4_Click(object sender, EventArgs e)//that button to stup the threads with the progressBar { t.Suspend(); t2.Suspend(); t3.Suspend(); } private void button2_Click(object sender, EventArgs e)// that is for contuniue after stuping { t.Resume(); t2.Resume(); t3.Resume(); } private void button3_Click(object sender, EventArgs e) // finally with that button you can remove all of the threads { t.Abort(); t2.Abort(); t3.Abort(); } }


Coloque ese código en una función (el código que no se puede ejecutar en el mismo hilo que la GUI), y para activar la ejecución de ese código, coloque lo siguiente.

Thread myThread= new Thread(nameOfFunction);

workerThread.Start();

Llamar a la función de inicio en el objeto de hilo causará la ejecución de su llamada de función en un nuevo hilo.


El ThreadPool.QueueUserWorkItem es bastante ideal para algo simple. La única advertencia es acceder a un control desde el otro hilo.

System.Threading.ThreadPool.QueueUserWorkItem(delegate { DoSomethingThatDoesntInvolveAControl(); }, null);


Hay muchas maneras de ejecutar subprocesos separados en .Net, cada uno tiene diferentes comportamientos. ¿Necesita continuar ejecutando el hilo después de que se cierre la GUI? ¿Necesita pasar información entre el hilo y la GUI? ¿El hilo necesita actualizar la GUI? ¿Debería el hilo hacer una tarea y luego salir, o debería continuar ejecutándose? Las respuestas a estas preguntas le dirán qué método usar.

Hay un buen artículo sobre el método asíncrono en el sitio web de Code Project que describe los diversos métodos y proporciona un código de muestra.

Tenga en cuenta que este artículo se escribió antes de que el patrón async/await y la biblioteca paralela de tareas se introdujeran en .NET.


Otra opción, que utiliza delegados y el grupo de subprocesos ...

Suponiendo que ''GetEnergyUsage'' es un método que toma un DateTime y otro DateTime como argumentos de entrada, y devuelve un Int ...

// following declaration of delegate ,,, public delegate long GetEnergyUsageDelegate(DateTime lastRunTime, DateTime procDateTime); // following inside of some client method GetEnergyUsageDelegate nrgDel = GetEnergyUsage; IAsyncResult aR = nrgDel.BeginInvoke(lastRunTime, procDT, null, null); while (!aR.IsCompleted) Thread.Sleep(500); int usageCnt = nrgDel.EndInvoke(aR);


Rápido y sucio, pero funcionará:

Utilizando en la parte superior:

using System.Threading;

código simple:

static void Main( string[] args ) { Thread t = new Thread( NewThread ); t.Start(); } static void NewThread() { //code goes here }

Acabo de lanzar esto en una nueva aplicación de consola para un ejemplo


Recomiendo mirar la Biblioteca de subprocesos de Power de Jeff Richter y específicamente el IAsyncEnumerator. Eche un vistazo al video en el blog de Charlie Calvert, donde Richter lo revisa para una buena visión general.

No se deje intimidar por el nombre porque hace que las tareas de programación asíncronas sean más fáciles de codificar.


Si quieres obtener un valor:

var someValue; Thread thread = new Thread(delegate() { //Do somthing and set your value someValue = "Hello World"; }); thread.Start(); while (thread.IsAlive) Application.DoEvents();


Si va a utilizar el objeto Thread sin procesar, entonces debe establecer IsBackground en true como mínimo y también debe configurar el modelo de Threading Apartment (probablemente STA).

public static void DoWork() { // do some work } public static void StartWorker() { Thread worker = new Thread(DoWork); worker.IsBackground = true; worker.SetApartmentState(System.Threading.ApartmentState.STA); worker.Start() }

Recomendaría la clase BackgroundWorker si necesita interacción con la interfaz de usuario.


Trate de usar la clase BackgroundWorker . Le da delegados para lo que debe ejecutar y para que se le notifique cuando el trabajo haya terminado. Hay un ejemplo en la página de MSDN que vinculé.


Un buen lugar para comenzar a leer es Joe Albahari .

Si desea crear su propio hilo, esto es lo más simple que puede obtener:

using System.Threading; new Thread(() => { Thread.CurrentThread.IsBackground = true; /* run your code here */ Console.WriteLine("Hello, world"); }).Start();


Cómo usar un hilo de fondo para buscar archivos

Tienes que tener mucho cuidado con el acceso desde otros subprocesos a cosas específicas de GUI (es común para muchos kits de herramientas de GUI). Si desea actualizar algo en la GUI desde el subproceso de procesamiento, verifique esta respuesta que creo que es útil para WinForms. Para WPF, vea this (muestra cómo tocar el componente en el método UpdateProgress () para que funcione desde otros subprocesos, pero en realidad no me gusta que no esté haciendo CheckAccess() antes de BeginInvoke través de Dispathcer, see y busque CheckAccess en eso)

Estaba buscando un libro específico de .NET sobre subprocesos y encontró este (descargable gratis). Consulte http://www.albahari.com/threading/ para obtener más detalles al respecto.

Creo que encontrará lo que necesita para iniciar la ejecución como un nuevo subproceso en las primeras 20 páginas y tiene muchos más (no estoy seguro acerca de los fragmentos específicos de GUI que me refiero estrictamente específicos a los subprocesos). Me encantaría saber qué piensa la comunidad sobre este trabajo porque estoy leyendo este. Por ahora se veía bastante ordenado para mí (para mostrar métodos y tipos específicos de .NET para subprocesos). También cubre .NET 2.0 (y no 1.1 antiguo) lo que realmente aprecio.


BackgroundWorker parece ser la mejor opción para ti.

Aquí está mi ejemplo mínimo. Después de hacer clic en el botón, el trabajador de fondo comenzará a trabajar en el hilo de fondo y también informará su progreso simultáneamente. También se informará una vez finalizado el trabajo.

using System.ComponentModel; ... private void button1_Click(object sender, EventArgs e) { BackgroundWorker bw = new BackgroundWorker(); // this allows our worker to report progress during work bw.WorkerReportsProgress = true; // what to do in the background thread bw.DoWork += new DoWorkEventHandler( delegate(object o, DoWorkEventArgs args) { BackgroundWorker b = o as BackgroundWorker; // do some simple processing for 10 seconds for (int i = 1; i <= 10; i++) { // report the progress in percent b.ReportProgress(i * 10); Thread.Sleep(1000); } }); // what to do when progress changed (update the progress bar for example) bw.ProgressChanged += new ProgressChangedEventHandler( delegate(object o, ProgressChangedEventArgs args) { label1.Text = string.Format("{0}% Completed", args.ProgressPercentage); }); // what to do when worker completes its task (notify the user) bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler( delegate(object o, RunWorkerCompletedEventArgs args) { label1.Text = "Finished!"; }); bw.RunWorkerAsync(); }

Nota:

  • Pongo todo en un solo método usando el método anónimo de C # por simplicidad, pero siempre puedes sacarlos a diferentes métodos.
  • Es seguro actualizar la GUI dentro de los controladores ProgressChanged o RunWorkerCompleted . Sin embargo, la actualización de la GUI desde DoWork provocará la InvalidOperationException .

// following declaration of delegate ,,, public delegate long GetEnergyUsageDelegate(DateTime lastRunTime, DateTime procDateTime); // following inside of some client method GetEnergyUsageDelegate nrgDel = GetEnergyUsage; IAsyncResult aR = nrgDel.BeginInvoke(lastRunTime, procDT, null, null); while (!aR.IsCompleted) Thread.Sleep(500); int usageCnt = nrgDel.EndInvoke(aR);

Charles su código (arriba) no es correcto. No es necesario que espere a que finalice. EndInvoke se bloqueará hasta que se señale WaitHandle.

Si desea bloquear hasta la finalización simplemente necesita

nrgDel.EndInvoke(nrgDel.BeginInvoke(lastRuntime,procDT,null,null));

o alternativamente

ar.AsyncWaitHandle.WaitOne();

¿Pero cuál es el punto de emitir llamadas anyc si bloquea? También podrías usar una llamada síncrona. Una mejor apuesta sería no bloquear y pasar un lambda para la limpieza:

nrgDel.BeginInvoke(lastRuntime,procDT,(ar)=> {ar.EndInvoke(ar);},null);

Una cosa a tener en cuenta es que debe llamar a EndInvoke. Mucha gente se olvida de esto y termina perdiendo el WaitHandle ya que la mayoría de las implementaciones asíncronas liberan el waithandle en EndInvoke.