7
votes

Existe-t-il un moyen d'utiliser la tâche comme un waihandle pour une valeur future t?

J'aimerais utiliser la récupération de la tâche d'une méthode pour renvoyer une valeur de la valeur lorsqu'il devient disponible ultérieurement, de sorte que l'appelant puisse bloquer à l'aide d'attendre ou de joindre une continuation ou même l'attendre. Le meilleur que je puisse penser, c'est que:

 public class Future<T> {
    private ManualResetEvent mre = new ManualResetEvent();
    private T value;
    public async Task<T> GetTask() {
        mre.WaitOne();
        return value;
    }
    public void Return(T value) {
        this.value = value;
        mre.Set();
    }
}


0 commentaires

3 Réponses :


0
votes

Ne pouvez-vous pas simplement tirer parti TASKEX.LOWNALL (T1, T2, T3 ...) Pour faire l'attente. Vous auriez besoin d'une vraie tâche qui représente le fait du travail, mais si vous avez dit quelque chose comme: xxx

Bien que vous puissiez probablement simplement attendre la tâche MyRealwork. Je ne vois pas dans votre code où la valeur est en cours de calcul. Cela pourrait nécessiter quelque chose comme: xxx


1 commentaires

Le problème que j'essaie de résoudre est que je n'ai pas de commisAvalueanDeanDeturne, mais que certains autres threads produisent indépendamment de quelqu'un qui demandent la tâche qui veut la valeur.



11
votes

Eh bien, je suppose que j'aurais dû creuser un peu plus avant de poster. TaskCompletsource Code> est exactement ce que je cherchais

var tcs = new TaskCompletionSource<int>();
bool completed = false;
var tc = tcs.Task.ContinueWith(t => completed = t.IsCompleted);
tcs.SetResult(1);
tc.Wait();
Assert.IsTrue(completed);


1 commentaires

J'utilise TaskCompletsource pour résoudre ce problème pour moi aussi - pour moi, c'est un gérant d'attente beaucoup plus élégant, car il est plus expressif à propos de votre opération d'origine. Exprimer une annulation ou des exceptions peut être très utile pour cascade aux consommateurs. :)



3
votes

Blocage d'un fil est mauvais en appelant le waithandle.waitone (), mais c'est ainsi que les événements fonctionnent et la réponse sélectionnée n'a pas beaucoup de sens, car elle ne fait rien de manière asynchrone.

Cependant, le. Frame-Filet peut utiliser des threads de travailleur à partir d'une piscine de thread pour attendre plusieurs événements en même temps (voir threadpool.registerwaitforSingleObjec t) - Cela améliorera l'utilisation globale des ressources dans votre application si vous devez attendre plusieurs withandles en même temps. P>

Alors quoi Vous pouvez faire, consiste à enregistrer le WAITHANDLE pour attendre un fil de travail et définissez le rappel avec la suite souhaitée. Avec la bibliothèque d'extension asyncwaithandle ( Nuget ) Ceci peut être fait en une ligne: P>

async Task MyCode()
{
  var mre = new ManualResetEvent();
  StartDoingSmthAsynchronouslyThatPulsesTheEvent(mre);
  await mre;
  // finish routine here when the event fires
}


0 commentaires