2009-10-08 7 views
7

Je suis en train d'implémenter un timeout sur une opération asynchrone (une série d'E/S réseau), et je ne suis pas sûr de ce qui est "meilleur" (du point de vue allocation/performance): créer un EventWaitHandle et en utilisant RegisterWaitForSingleObject, ou simplement en créant un temporisateur et en utilisant son Tick.Temporisations .Net: WaitForSingleObject vs Timer

Dans mon cas spécifique, EventWaitHandle est créé paresseusement, mais il est évident qu'il doit être instancié pour utiliser WaitForSingleObject. Donc, c'est vraiment une question sur le coût des ressources d'un WaitHandle + WaitForSingleObject vs un minuteur. Les deux approches sont à peu près aussi faciles à mettre en œuvre.

J'ai implémenté les deux à différents moments, donc je comprends le terrain, je ne suis pas sûr de l'approche qui est 'meilleure'.

Répondre

3

Microsoft Morgan Skinner seems to prefer RegisterWaitForSingleObject.

En ce qui concerne les allocations, le réflecteur révèle que RegisterWaitForSingleObject créer une instance d'un RegisteredWaitHandle, alors qu'une minuterie crée un TimerBase interne, ainsi qu'une classe nommée _TimerCallback. On pourrait continuer et comparer les tailles de ces classes et ainsi de suite, mais elles semblent avoir plus de dépendances, en particulier celles qui ne sont pas gérées (les deux utilisent des fonctions win32 sous-jacentes) - donc je ne peux vraiment pas donner de réponse directe. Cependant, gardez à l'esprit que vous pouvez allouer un seul Maunal/AutoResetEvent et le passer à tous les appels (puisque vous comptez sur le timeout, donc vous ne le signalerez jamais) .

En ce qui concerne les performances, je ne suis pas sûr non plus. ThreadPool utilisera un thread d'attente spécial pour chaque 63 actions enregistrées via RegisterWaitForSingleObject. En revanche, une minuterie utilisera un minuteur win32 sous-jacent. Les deux finiront par utiliser un thread de travail ThreadPool pour l'exécution réelle. Quel est le meilleur dans quels scénarios? Beats me .. donc je partirais avec Skinner sur celui-ci :)

Voir aussi:

+0

Son article de blog est un bonne comparaison des usages, mais n'est pas une recommandation très forte de favoriser l'un contre l'autre. Et plus j'y pensais, plus je ne voyais aucune différence en termes de transitions du noyau et ainsi de suite. J'aimerais toujours savoir s'il y avait une différence de coût par rapport à l'API Win32 sous-jacente, mais le poids de l'implémentation de .net semble être la meilleure réponse que j'ai trouvée. – piers7

1

Rien n'est mieux. Une minuterie est utilisée pour «piquer» votre fil périodiquement afin de faire quelque chose. WaitForSingleObject attend sur les handles. Le délai d'attente est là pour que vous puissiez l'utiliser pour décider d'arrêter d'attendre au lieu d'être coincé dans l'impasse. L'utilisation d'une minuterie pour rompre le waitforsingleobject d'un verrou n'est pas nécessaire si vous utilisez le délai d'expiration.

Le coût des ressources est négligeable pour les deux. Je ne peux pas dire quelle approche vous devriez utiliser parce qu'elle dépend fortement de la situation de code que vous avez.

+2

Je ne suis pas d'accord. C'est une question simple: coût d'allocation d'un minuteur vs coût d'allocation d'un waithandle et d'un WaitForSingleObject. Ils sont les deux ressources du système d'exploitation. L'un doit coûter plus cher que l'autre, quelle que soit ma situation. Et tandis que dans ce scénario, je parle d'une minuterie «one off», * les deux * peuvent être utilisés pour «piquer» périodiquement votre code - vous pouvez utiliser le drapeau «executeOnlyOnce» sur RegisterWaitForSingleObject ... – piers7