Meilleure façon de rendre des événements asynchrones en C #
-
09-06-2019 - |
Question
Les événements sont synchrones en C #. J'ai cette application où ma forme principale commence un fil avec une boucle dans ce qui écoute un flux. Lorsqu'un événement survient dans le flux, un événement est déclenché de la boucle au formulaire principal.
Si le formulaire principal est lent ou affiche une boîte de message ou quelque chose, la boucle sera suspendue. Quel est le meilleur moyen de contourner cela? En utilisant un rappel et invoquer sur le formulaire principal?
La solution
Hmmm, j'ai utilisé différents scénarios qui dépendaient de ce dont j'avais besoin à l'époque.
Je pense que BeginInvoke serait probablement le plus facile à coder puisque vous y êtes presque. Dans les deux cas, vous devriez déjà utiliser Invoke. Il suffit donc de passer à BeginInvoke. Utiliser un rappel sur un thread distinct accomplira le même travail (tant que vous utiliserez le pool de threads pour mettre le rappel en file d'attente) et utiliser BeginInvoke.
Autres conseils
Puisque vous utilisez un formulaire, le moyen le plus simple consiste à utiliser Composant BackgroundWorker .
La classe BackgroundWorker vous permet pour exécuter une opération sur un séparé, fil dédié. Long des opérations comme les téléchargements et la base de données les transactions peuvent causer votre utilisateur interface (interface utilisateur) pour sembler comme si a cessé de répondre pendant qu'ils sont fonctionnement. Quand vous voulez une interface utilisateur réactive et vous êtes confronté à de longs délais associés à de telles opérations, le La classe BackgroundWorker fournit une solution pratique.
événements ne sont que des délégués , utilisez donc BeginInvoke. (voir Appels de méthodes asynchrones dans l'environnement .NET )
Vous avez quelques options, comme cela a déjà été détaillé, mais selon mon expérience, il vaut mieux laisser les délégués et BeginInvoke, et utiliser BackgroundWorker à la place (v2.0 +), car il est plus facile à utiliser et vous permet également de interagir avec le formulaire principal à la fin du fil. Dans l’ensemble, j’ai trouvé une solution très bien mise en œuvre.
System.ComponentModel.BackgroundWorker est en effet un bon point de départ. Il effectuera votre travail asynchrone, vous notifiera des événements importants et vous permettra de mieux vous intégrer à vos formulaires.
Par exemple, vous pouvez activer les notifications de progression en enregistrant un gestionnaire pour l'événement ProgressChanged. (ce qui est vivement recommandé si vous utilisez un processus long et asynchrone et que vous ne voulez pas que l'utilisateur pense que l'application est figée)