c# - tareas - ejemplos de delegar funciones
Delegar una tarea y recibir una notificación cuando se complete(en C#) (7)
Conceptualmente, me gustaría lograr lo siguiente, pero he tenido problemas para entender cómo codificarlo correctamente en C #:
SomeMethod { // Member of AClass{}
DoSomething;
Start WorkerMethod() from BClass in another thread;
DoSomethingElse;
}
Luego, cuando WorkerMethod () esté completo, ejecuta esto:
void SomeOtherMethod() // Also member of AClass{}
{ ... }
¿Alguien puede dar un ejemplo de eso?
Aunque hay varias posibilidades aquí, usaría un delegado, llamado asincrónicamente usando el método BeginInvoke
.
Advertencia : no olvide llamar siempre a EndInvoke
en IAsyncResult
para evitar fugas de memoria eventuales, como se describe en este artículo .
Echa un vistazo a BackgroundWorker.
En .Net 2 se introdujo el BackgroundWorker, esto hace que las operaciones asincrónicas sean realmente fáciles:
BackgroundWorker bw = new BackgroundWorker { WorkerReportsProgress = true };
bw.DoWork += (sender, e) =>
{
//what happens here must not touch the form
//as it''s in a different thread
};
bw.ProgressChanged += ( sender, e ) =>
{
//update progress bars here
};
bw.RunWorkerCompleted += (sender, e) =>
{
//now you''re back in the UI thread you can update the form
//remember to dispose of bw now
};
worker.RunWorkerAsync();
En .Net 1 tienes que usar hilos.
La clase BackgroundWorker se agregó a .NET 2.0 para este propósito exacto.
En resumen, haces:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate { myBClass.DoHardWork(); }
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(SomeOtherMethod);
worker.RunWorkerAsync();
También puede agregar cosas elegantes como cancelación e informes de progreso si lo desea :)
Ok, no estoy seguro de cómo quieres hacerlo. Según su ejemplo, parece que WorkerMethod no crea su propio hilo para ejecutar bajo, pero desea llamar a ese método en otro hilo.
En ese caso, cree un método de trabajo breve que llame a WorkerMethod y luego llame a SomeOtherMethod, y ponga ese método en cola en otro hilo. Luego, cuando WorkerMethod se completa, se llama SomeOtherMethod. Por ejemplo:
public class AClass
{
public void SomeMethod()
{
DoSomething();
ThreadPool.QueueUserWorkItem(delegate(object state)
{
BClass.WorkerMethod();
SomeOtherMethod();
});
DoSomethingElse();
}
private void SomeOtherMethod()
{
// handle the fact that WorkerMethod has completed.
// Note that this is called on the Worker Thread, not
// the main thread.
}
}
Tienes que usar AsyncCallBacks. Puede usar AsyncCallBacks para especificar un delegado a un método, y luego especificar los métodos CallBack que se llaman una vez que se completa la ejecución del método objetivo.
Aquí hay un pequeño ejemplo, ejecútelo y véalo usted mismo.
Programa de clase {
public delegate void AsyncMethodCaller();
public static void WorkerMethod()
{
Console.WriteLine("I am the first method that is called.");
Thread.Sleep(5000);
Console.WriteLine("Exiting from WorkerMethod.");
}
public static void SomeOtherMethod(IAsyncResult result)
{
Console.WriteLine("I am called after the Worker Method completes.");
}
static void Main(string[] args)
{
AsyncMethodCaller asyncCaller = new AsyncMethodCaller(WorkerMethod);
AsyncCallback callBack = new AsyncCallback(SomeOtherMethod);
IAsyncResult result = asyncCaller.BeginInvoke(callBack, null);
Console.WriteLine("Worker method has been called.");
Console.WriteLine("Waiting for all invocations to complete.");
Console.Read();
}
}
Use delegados asincrónicos:
// Method that does the real work
public int SomeMethod(int someInput)
{
Thread.Sleep(20);
Console.WriteLine(”Processed input : {0}”,someInput);
return someInput+1;
}
// Method that will be called after work is complete
public void EndSomeOtherMethod(IAsyncResult result)
{
SomeMethodDelegate myDelegate = result.AsyncState as SomeMethodDelegate;
// obtain the result
int resultVal = myDelegate.EndInvoke(result);
Console.WriteLine(”Returned output : {0}”,resultVal);
}
// Define a delegate
delegate int SomeMethodDelegate(int someInput);
SomeMethodDelegate someMethodDelegate = SomeMethod;
// Call the method that does the real work
// Give the method name that must be called once the work is completed.
someMethodDelegate.BeginInvoke(10, // Input parameter to SomeMethod()
EndSomeOtherMethod, // Callback Method
someMethodDelegate); // AsyncState