J'ai implémenté le filetage dans mon application pour graver des sites Web. Une fois tous les sites mis au rebut, je veux les traiter. Le formulaire crée un travailleur de la file d'attente (qui crée 2 travailleurs et traite les tâches). Une fois toutes les tâches terminées, je veux les traiter dans le formthread. A ce stade, j'accieved cela avecProgression du fil vers l'interface graphique
public void WaitForCompletion()
{
// Enqueue one null task per worker to make each exit.
StopWorkers();
//wait for the workers to finish
foreach (Thread worker in workers)
{
worker.Join();
}
}
Après une tâche préformées je tire (de queueworker):
public event EventHandler<ProgressEvent> UrlScanned;
if (UrlScanned != null)
{
UrlScanned(this, new ProgressEvent(task.Name, 1));
}
et attraper cet événement avec:
urlscanner.UrlScanned += new EventHandler<ProgressEvent>(UrlScanningProgress);
private void UrlScanningProgress(object sender, ProgressEvent args)
{
if (pbarurlScan.InvokeRequired)
{
//don't use invoke when Thread.Join() is used! Deadlock
Invoke(new MethodInvoker(delegate() { UrlScanningProgress(sender, args);
//BeginInvoke(new MethodInvoker(delegate() { UrlScanningProgress(sender, args)};
}
else
{
pbarurlScan.Value++;
}
}
Le problème est que le thread de formulaire est bloqué et en appelant Invoke l'application entière est maintenant dans une situation de blocage.
Comment puis-je donner à la mise à jour formthread sans avoir une impasse et ont une mise à jour immidiate (BeginInvoke se produit si les fils des travailleurs se font)
J'ai utilisé la jointure pour attendre 'tout simplement' que tout soit fait. Créez donc un gestionnaire UrlScanningComplete dans le formulaire. Et déclencher un événement à partir du travailleur de la file d'attente si toutes les tâches sont effectuées? – RvdK
Cette approche serait correcte - mais vous devez toujours basculer vers le thread d'interface utilisateur (Invoke/BeginInvoke) à un moment donné avant d'effectuer un travail réel sur le formulaire. –