Je sais comment faire des méthodes Async mais disons que j'ai une méthode qui fait beaucoup de travail puis renvoie une valeur booléenne?
Comment renvoyer la valeur booléenne sur le rappel?
Clarification:
public bool Foo(){
Thread.Sleep(100000); // Do work
return true;
}
Je veux être capable de rendre cela asynchrone.
Il y a plusieurs façons de faire cela ... la plus simple consiste à faire en sorte que la méthode asynchrone effectue également l'opération suivante. Une autre approche populaire consiste à passer un rappel, c'est-à-dire.
void RunFooAsync(..., Action<bool> callback) {
// do some stuff
bool result = ...
if(callback != null) callback(result);
}
Une autre approche consiste à déclencher un événement (avec le résultat dans les données event-args) lorsque l'opération asynchrone est terminée.
De plus, si vous utilisez la TPL, vous pouvez utiliser ContinueWith
:
Task<bool> outerTask = ...;
outerTask.ContinueWith(task =>
{
bool result = task.Result;
// do something with that
});
A partir de C # 5. , vous pouvez spécifier la méthode comme suit:
public async Task<bool> doAsyncOperation()
{
// do work
return true;
}
bool result = await doAsyncOperation();
La manière la plus simple de le faire est probablement de créer un délégué puis BeginInvoke
, suivi d’une attente à l’avenir, et d’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);
}
Utilisez un BackgroundWorker. Il vous permettra d’obtenir des rappels à la fin et de suivre vos progrès. Vous pouvez définir la valeur Result sur les arguments de l'événement avec la valeur résultante.
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;
}
Peut-être que vous pouvez essayer de commencer en invitant un délégué pointant sur votre méthode comme ceci:
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);
}
}
Ensuite, utilisez la valeur de la méthode que vous avez envoyée en tant que AsyncCallback pour continuer.