Observer le morceau de code suivant:
var handler = GetTheRightHandler();
var bw = new BackgroundWorker();
bw.RunWorkerCompleted += OnAsyncOperationCompleted;
bw.DoWork += OnDoWorkLoadChildren;
bw.RunWorkerAsync(handler);
Maintenant, supposons que je veux attendre d' bw
finitions de travail. Quelle est la bonne façon de le faire?
Ma solution est:
bool finished = false;
var handler = GetTheRightHandler();
var bw = new BackgroundWorker();
bw.RunWorkerCompleted += (sender, args) =>
{
OnAsyncOperationCompleted(sender, args);
finished = true;
});
bw.DoWork += OnDoWorkLoadChildren;
bw.RunWorkerAsync(handler);
int timeout = N;
while (!finished && timeout > 0)
{
Thread.Sleep(1000);
--timeout;
}
if (!finished)
{
throw new TimedoutException("bla bla bla");
}
Mais je n'aime pas ça.
J'ai examiné le remplacement de l' finished
drapeau avec un événement de synchronisation, de le fixer dans l' RunWorkerCompleted
de gestionnaire et de bloquer par la suite au lieu de faire de la alors le sommeil de la boucle.
Hélas, c'est faux, car le code peut s'exécuter dans le WPF ou WindowsForm contexte de synchronisation, dans lequel cas, je bloque le même thread que l' RunWorkerCompleted
gestionnaire s'exécute sur, qui n'est clairement pas très intelligent.
Je voudrais savoir d'une meilleure solution.
Merci.
EDIT:
P. S.
- L'exemple de code est donc artificiel, intentionnellement pour préciser ma question. Je suis parfaitement conscient de l'achèvement de rappel et pourtant, je veux savoir comment faire pour attendre jusqu'à l'achèvement. C'est ma question.
- Je suis conscient de l'
Thread.Join
,Delegate.BeginInvoke
,ThreadPool.QueueUserWorkItem
, etc... La question est précisément à propos deBackgroundWorker
.
EDIT 2:
OK, je suppose que ce sera beaucoup plus facile si j'explique le scénario.
J'ai une unité de la méthode d'essai, qui appelle certains de code asynchrone, qui à son tour en fin de compte s'engage dans un BackgroundWorker
, à laquelle je suis capable de passer un gestionnaire d'achèvement. Tout le code est le mien, donc je peux changer la mise en œuvre, si je désire.
Je ne vais pas, cependant, pour remplacer l' BackgroundWorker
, parce qu'il utilise automatiquement le droit de contexte de synchronisation, de sorte que lorsque le code est invoquée sur un thread d'INTERFACE utilisateur à l'achèvement de rappel est appelée sur le même thread de l'INTERFACE utilisateur, ce qui est très bon.
De toute façon, il est possible que l'unité de la méthode de test des hits de la fin, avant le BW a terminé son travail, qui n'est pas bon. Je souhaite donc à attendre jusqu'à ce que le BW complète et voudrais savoir le meilleur moyen pour elle.
Il y a plus de pièces, mais le tableau d'ensemble est plus ou moins comme je viens de décrire.