c# - sobreescritos - ¿Cómo hacer que un Método Asíncrono devuelva un valor?
no se puede usar await en void (6)
Sé cómo hacer métodos Async pero digo que tengo un método que hace mucho trabajo y luego devuelve un valor booleano.
¿Cómo devuelvo el valor booleano en la devolución de llamada?
Aclaración :
public bool Foo(){
Thread.Sleep(100000); // Do work
return true;
}
Quiero ser capaz de hacer esto asincrónico.
Deberías usar el EndXXX de tu método async para devolver el valor. EndXXX debe esperar hasta que haya un resultado usando WaitHandle de IAsyncResult y luego regresar con el valor.
Desde C # 5.0 , puede especificar el método como
public async Task<bool> doAsyncOperation()
{
// do work
return true;
}
bool result = await doAsyncOperation();
Hay algunas maneras de hacerlo ... lo más simple es hacer que el método async también realice la operación de seguimiento. Otro enfoque popular es pasar una devolución de llamada, es decir,
void RunFooAsync(..., Action<bool> callback) {
// do some stuff
bool result = ...
if(callback != null) callback(result);
}
Otro enfoque sería plantear un evento (con el resultado en los datos de args del evento) cuando se completa la operación de sincronización.
Además, si está utilizando el TPL, puede usar ContinueWith
:
Task<bool> outerTask = ...;
outerTask.ContinueWith(task =>
{
bool result = task.Result;
// do something with that
});
Probablemente la forma más sencilla de hacerlo es crear un delegado y luego BeginInvoke
, seguido de una espera en algún momento en el futuro, y un EndInvoke
.
public bool Foo(){
Thread.Sleep(100000); // Do work
return true;
}
public SomeMethod()
{
var fooCaller = new Func<bool>(Foo);
// Call the method asynchronously
var asyncResult = fooCaller.BeginInvoke(null, null);
// Potentially do other work while the asynchronous method is executing.
// Finally, wait for result
asyncResult.AsyncWaitHandle.WaitOne();
bool fooResult = fooCaller.EndInvoke(asyncResult);
Console.WriteLine("Foo returned {0}", fooResult);
}
Tal vez puedas intentar BeginInvocar a un delegado que apunta a tu método así:
delegate string SynchOperation(string value);
class Program
{
static void Main(string[] args)
{
BeginTheSynchronousOperation(CallbackOperation, "my value");
Console.ReadLine();
}
static void BeginTheSynchronousOperation(AsyncCallback callback, string value)
{
SynchOperation op = new SynchOperation(SynchronousOperation);
op.BeginInvoke(value, callback, op);
}
static string SynchronousOperation(string value)
{
Thread.Sleep(10000);
return value;
}
static void CallbackOperation(IAsyncResult result)
{
// get your delegate
var ar = result.AsyncState as SynchOperation;
// end invoke and get value
var returned = ar.EndInvoke(result);
Console.WriteLine(returned);
}
}
Luego use el valor en el método que envió como AsyncCallback para continuar.
Use un BackgroundWorker. Le permitirá recibir devoluciones de llamada al finalizar y le permitirá seguir el progreso. Puede establecer el valor de Resultado en los argumentos del evento en el valor resultante.
public void UseBackgroundWorker()
{
var worker = new BackgroundWorker();
worker.DoWork += DoWork;
worker.RunWorkerCompleted += WorkDone;
worker.RunWorkerAsync("input");
}
public void DoWork(object sender, DoWorkEventArgs e)
{
e.Result = e.Argument.Equals("input");
Thread.Sleep(1000);
}
public void WorkDone(object sender, RunWorkerCompletedEventArgs e)
{
var result = (bool) e.Result;
}