J'ai plusieurs zones de texte dans mon application wpf. L'événement LostFocus de chaque zone de texte démarre un arrière-plan pour envoyer les données à un port série connecté.wpf C# backgroundworker attente jusqu'à la fin
private readonly BackgroundWorker online_mode_send_worker = new BackgroundWorker();
online_mode_send_worker.DoWork += online_mode_send_worker_DoWork;
online_mode_send_worker.RunWorkerCompleted += online_mode_send_worker_RunWorkerCompleted;
private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
online_mode_send_worker.RunWorkerAsync(data);
}
private void online_mode_send_worker_DoWork(object sender, DoWorkEventArgs e)
{
List<object> data = (List<object>)e.Argument;
Port.WriteLine(STARTCHARACTER + XMLSET + XML_TAG_START + data[0] + XML_TAG_STOP + data[1] + ENDCHARACTER);
string received = Port.ReadLine();
}
private void online_mode_send_worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//do some things after worker completed
}
À ce stade, tout fonctionne correctement.
Mais parfois je dois envoyer deux points de données directement l'un après l'autre et là j'ai un problème.
private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
online_mode_send_worker.RunWorkerAsync(data1);
//wait until backgroundworker has finished
online_mode_send_worker.RunWorkerAsync(data2);
}
Le Backgroundworker
est toujours en cours d'exécution et je reçois une exception levée. Est-il possible d'attendre après le premier online_mode_send_worker.RunWorkerAsync(data)
jusqu'à ce qu'il ait fini et ensuite commencer le deuxième online_mode_send_worker.RunWorkerAsync(data)
?
while(online_mode_send_worker.isBusy);
ne fonctionne pas parce que le thread principal est le blocage et la RunWorkerCompleted()
n'est pas jeté et donc le Backgroundwoker
est toujours occupé.
J'ai trouvé quelque chose comme ceci, mais Application.DoEvents()
n'est pas disponible en wpf.
while (online_mode_send_worker.IsBusy)
{
Application.DoEvents();
System.Threading.Thread.Sleep(100);
}
moins que quelque chose existe déjà je penser que vous pouvez créer un service qui encapsule le travailleur de fond. cette classe aura également une file d'attente. pour contenir des données. lorsque le travail est démarré, le travailleur traite les données. Si plus de données doivent être envoyées, ajoutez-les à la file d'attente. lorsque le travailleur l'exécute, il vérifie la file d'attente pour voir s'il y a plus de travail à faire et supprime la file d'attente du travail suivant et appelle à nouveau le travailleur d'arrière-plan sinon il termine normalement. – Nkosi
Utilisez 'Tâche' au lieu de Travailleur de fond. Il semble vraiment démodé d'utiliser un Backgroundworker. https://www.dotnetperls.com/async – Mat
Voir msdn: https://msdn.microsoft.com/fr-fr/library/58195swd(v=vs.110).aspx – jdweng