2009-10-21 8 views
29

Tengo dos funciones que quiero ejecutar en diferentes hilos (porque son cosas de la base de datos, y no se necesitan de inmediato).¿La mejor manera de ejecutar una función simple en un nuevo subproceso?

Las funciones son:

  getTenantReciept_UnitTableAdapter1.Fill(rentalEaseDataSet1.GetTenantReciept_Unit); 
      getTenantReciept_TenantNameTableAdapter1.Fill(rentalEaseDataSet1.GetTenantReciept_TenantName); 

en JavaScript, sé que puedo crear crear una función anónima y llamarlo en un nuevo hilo con bastante facilidad con algo como esto:

setTimeout(new function(){doSomethingImportantInBackground();}, 500); 

¿Hay algo como esto en C#?

+2

Solo un lado, pero ese código JavaScript no ** llama ** a una función en un nuevo hilo, solo lo programa para ejecutarse en el futuro. Javascript es de subproceso único, por lo que todo el código se ejecuta en el mismo hilo. –

Respuesta

66

Su pregunta no es muy clara, me temo. Usted puede comenzar un nuevo hilo con algo de código, usando métodos anónimos en C# 2, y las expresiones lambda en C# 3:

Anónimo método:

new Thread(delegate() { 
    getTenantReciept_UnitTableAdapter1.Fill(
     rentalEaseDataSet1.GetTenantReciept_Unit); 
}).Start(); 
new Thread(delegate() { 
    getTenantReciept_TenantNameTableAdapter1.Fill(
     rentalEaseDataSet1.GetTenantReciept_TenantName); 
}).Start(); 

Lambda expresión:

new Thread(() => 
    getTenantReciept_UnitTableAdapter1.Fill(
     rentalEaseDataSet1.GetTenantReciept_Unit) 
).Start(); 
new Thread(() => 
    getTenantReciept_TenantNameTableAdapter1.Fill(
     rentalEaseDataSet1.GetTenantReciept_TenantName) 
).Start(); 

usted puede usar el mismo tipo de sintaxis para Control.Invoke, pero es un poco más complicado ya que puede tomar cualquier delegado, por lo que debe decirle al compilador qué tipo está utilizando en lugar de confiar en una conversión implícita. Es probable que sea más fácil de escribir:

EventHandler eh = delegate 
{ 
    // Code 
}; 
control.Invoke(eh); 

o

EventHandler eh = (sender, args) => 
{ 
    // Code 
}; 
control.Invoke(eh); 

Como nota al margen, son sus nombres realmente tan larga? ¿Puedes acortarlos para obtener un código más legible?

+0

Creo que el OP quería que cada llamada a Fill() se ejecutara en su propio hilo. Pero aparte de eso, en el clavo. – LBushkin

+0

@LBushkin: Se ajustará. No es una pregunta muy clara, para ser honesto. –

+0

Iba a expandir mi respuesta para incluir la de lambda, pero la tuya es más completa (y mejor) de todos modos. Un componente de trabajador en segundo plano aún es una opción, ya que no tiene que preocuparse por Control.Invocar. – RichardOD

6

Se podría utilizar un método anónimo:


void Foo() 
{ 
    Thread myThread = new System.Threading.Thread(delegate(){ 
       //Your code here 
    }); 
    myThread.Start(); 
} 
+1

Otorga un error Operación de cruce de hilos no válida: Control al que se accede desde un hilo que no sea el hilo en el que se creó. –

+0

@PrakashVishwakarma Esto se debe a que está accediendo a un elemento de control de su formulario, pero en un subproceso diferente del subproceso de interfaz de usuario. Necesitas hacer textboxInput.Invoke (nuevo MethodInvoker (() => {Whatever();})); y programará la función anónima() => {Whatever(); } en el hilo de UI. –

10

partir de hilos es relativamente caro.

Usted podría ser mejor de usar un hilo desde el grupo de subprocesos:

ThreadPool.QueueUserWorkItem(unused => 
    getTenantReciept_UnitTableAdapter1.Fill(
     rentalEaseDataSet1.GetTenantReciept_Unit) 
); 
ThreadPool.QueueUserWorkItem(unused => 
    getTenantReciept_TenantNameTableAdapter1.Fill(
     rentalEaseDataSet1.GetTenantReciept_TenantName) 
); 
+0

¿Cómo sabes cuando los hilos están completos? Ie. Lo hice: 'ThreadPool.QueueUserWorkItem (sin usar => datos [0] = get_data (a, b));' 'ThreadPool.QueueUserWorkItem (sin usar => datos [1] = get_data (a2, b2));' –

+1

Es 2016 ahora. 'ThreadPool.QueueUserWorkItem' es tan 2009. Utilice las tareas (vea @JSideris) respuesta, o 'async'. Ambos proporcionan formas de esperar a que la tarea termine y recuperar un valor de retorno. – oefe

22

Similar a lo que se ha dicho - Encuentro tareas a ser un poco más simple (con el apoyo como de .net 4 y puede ser utilizado de la siguiente manera tan de .net 4.5):

Task mytask = Task.Run(() => 
{ 
    //Lines of code 
}); 
+0

No hay método Run en .net 4 – Tommix

+1

Corrección realizada: las tareas estuvieron disponibles en .net 4 pero la sintaxis 'Task.Run' fue admitida en .net 4.5. – JSideris

Cuestiones relacionadas