J'ai une question de filetage assez simple. p>
J'écris un utilitaire simple qui exécutera divers scripts SQL basés sur des paramètres définis par l'utilisateur. P>
Afin de conserver l'interface utilisateur réactive et de fournir des commentaires sur l'état des scripts en cours d'exécution, j'ai décidé que l'utilisation de Cependant, je suis un peu confus quant à la manière dont je peux relancer les informations de sortie que SMO reviendra sur le fil de l'interface utilisateur. P>
Pour cet utilitaire, j'utilise WPF et MVVM pour la présentation. Je pense que j'aurais une classe code> scriptworker CODE> que je pourrais transmettre les paramètres et les emplacements et à l'ordre dans lequel exécuter les scripts à. P>
Après avoir exécuté chaque script, je voudrais renvoyer des résultats sur le thread de l'interface utilisateur afin qu'il met à jour la fenêtre de sortie, puis je voudrais que le travailleur passe à la tâche suivante. P>
Je suis certain que c'est une question fondamentale, mais après avoir examiné Je basse mes hypothèses de cet article Microsoft: P>
http://msdn.microsoft.com/ EN-US / Bibliothèque / 3DASC8AS (vs.80) .aspx P>
Merci pour l'info! P> threadpool.quaueueuerworkitem code> serait appropriée pour gérer l'exécution du Divers scripts (via SMO.) P>
weeuueropeworkitem cod> et que je commence essentiellement au travail via un rappel, je ne sais pas comment j'absais ce que j'aurais accompli tiens à accomplir. p>
3 Réponses :
Cet article a un exemple simple de ce que vous voulez.
Pour revenir au fil de l'interface utilisateur, vous avez besoin d'une référence à dans pseudocode, vous pouvez faire quelque chose comme ceci: p> Notez que la sortie code> Dans cet exemple, c'est un contrôle et implémente donc également l'interface code> isynchronizeinvoke code> afin que vous puissiez également choisir d'appeler L'approche esquissée ci-dessus est plutôt bas de niveau mais vous donne beaucoup de contrôle, en particulier sur la manière dont vous souhaitez signaler des progrès. isynchronizeinvoke code>
interface. formulaire code> a > Classe, par exemple, implémente cette interface. P>
invoquer code> directement sur ce contrôle. p>
Backworker CODE>
vous donne une solution plus de haut niveau mais moins de contrôle. Vous ne pouvez fournir que des états de progression via le non typé de Userstate code>
propriété. P> p>
-1: l'interface isynchronizeInvoke IsynchronizeInvoke IsynchronizeVoke n'a pas été reportée dans WPF et n'est pas pris en charge dans ce cadre d'interface utilisateur.
Je recommande d'utiliser la nouvelle fonction de tâche code> de .NET 4.0. Il fait exactement ce que vous voulez, y compris la synchronisation du résultat ou des conditions d'erreur à un autre thread (le fil de l'interface utilisateur, dans ce cas). P>
Si .NET 4.0 n'est pas une option, je vous recommanderais que L'option code> code> est très agréable car elle gère très naturellement les tâches parents / enfants. Le seul endroit où résumer, par ordre de préférence: p>
Comme vous pouvez le constater, WeeuUserSerWorkItem code> fonctionnerait techniquement, mais est extrêmement bas niveau. Il y a des moyens plus facilement. P>
Backworker code> (si votre traitement de fond n'est pas trop complexe) ou des délégués asynchrones tels que Hans mentionnés. Si vous utilisez des délégués ASYNC, utilisez la classe
asyncoperation code> pour prélever les résultats sur le thread de l'interface utilisateur. P>
Backworker code> ne peut pas être imbriqué. Une autre considération est l'annulation;
Tâche Code> et
Backworker CODE> Ayez un support intégré pour l'annulation, mais pour les délégués ASYNC, vous devez faire le vôtre. P>
tâche code> est un peu plus complexe que
Backworker code> est en cours de rapport. Ce n'est pas aussi facile que
Backworker code>, mais j'ai un wrapper sur mon blog pour minimiser cela. P>
Tâche CODE> - Soutient le maréchalage approprié des erreurs, le concept d'un résultat, d'annulation et de nidification parent / enfant. Son une faiblesse est que le rapport d'avancement n'est pas simple (vous devez créer une autre tâche et la planifier sur le fil de l'interface utilisateur). LI>
Backworker CODE> - Soutient le maréchalage approprié des erreurs, le concept d'un résultat, d'annulation et de rapport d'avancement. Sa seule faiblesse est que cela ne supporte pas
Nidification parent / enfant, et qui limite son utilisation dans APIS, par exemple, pour une couche d'entreprise. LI>
délégué.beginInvoke code> avec
asyncopération code> - prend en charge la mise en place correcte des erros, le concept d'un résultat et des rapports d'avancement. Cependant, il n'y a pas de concept intégré d'annulation (bien qu'elle puisse être faite à la main à l'aide d'un
volatile bool code>). Il ne supporte pas non plus la nidification des parents / enfants. Li>
délégué.begininvoke code> avec
SynchronizationContext code> - Ceci est identique à l'option (3), sauf qu'il utilise
synchronisationContext code> directement. Le code est légèrement plus complexe, mais le compromis est que la nidification parent / enfant est prise en charge. Toutes les autres limitations sont identiques à l'option (3). Li>
threadpool.QueueUserSerWorkItem code> avec
asyncopération code> ou
synchronisationContext code> - prend en charge le concept de déclaration d'avancement. L'annulation souffre du même problème que l'option (3). Le maréchalage des erreurs n'est pas facile (en particulier, préservant la trace de la pile). En outre, la nidification parent / enfant n'est possible que si le
synchronisationContext code> est utilisé à la place de
asyncopération code>. En outre, cette option ne prend pas en charge le concept d'un résultat, de sorte que toute valeur de retour doit être transmise en tant qu'arguments. LI>
ol>
Tâche code> est le gagnant clair. Il devrait être utilisé à moins que .NET 4.0 n'est pas une option. P>
Merci pour la réponse détaillée!
@Stephen Merci pour l'explication et la ventilation élargie. C'est très utile pour comprendre les différentes manières. Au fait, le lien vers votre blog semble être obsolète.
Le Fonctionnalité de nidification parent / enfant n'a pas bien vieilli. Personne n'utilise, et Microsoft souhaite qu'ils puissent revenir dans le temps et l'inventer!
Je sais que c'est une question ancienne, mais je pense que WeeueUserSerWorkItem est utile lorsque vous souhaitez un fil rapide pour le test sans avoir ASYNC / attendre une intoxication qui vient souvent avec la tâche.
Utilisez Dispatcher.Invoke pour obtenir des informations de la File d'attente de message de fenêtre. p>
Exemple de test d'une analyse RFID sans avoir le périphérique réel: P>
ThreadPool.QueueUserWorkItem(WaitCallback); private void WaitCallback(object state) { while (true) { string tid = tids[curtid++ % tids.Count()]; bool orderShowing = Dispatcher.Invoke(() => { return ContentArea.Content == default; }); if (orderShowing) Dispatcher.Invoke(() => { OnRFIDScan(null, new RFIDArgs { TIDHex = tid }); }); Thread.Sleep(10000); } }
Je jetterais un coup d'oeil à la classe de bus d'arrière-plan. Il est facile de faire fonctionner un processus d'arrière-plan et d'envoyer des mises à jour sur le fil de l'interface utilisateur.