Dupliquer renvoyé par Guid.NewGuid ()?

Nous avons une application qui génère des données simulées pour l’un de nos services à des fins de test. Chaque élément de données a un Guid unique. Cependant, lorsque nous avons exécuté un test après quelques modifications mineures du code dans le simulateur, tous les objects générés par celui-ci avaient le même Guid.

Un seul object de données a été créé, puis une boucle for dans laquelle les propriétés de l’object ont été modifiées, y compris un nouveau Guid unique et envoyé au service via remoting (sérialisable, pas marshal-by-ref, si c’est ce que vous voulez réfléchis), boucle et recommence, etc.

Si nous mettons un petit Thread.Sleep (…) à l’intérieur de la boucle, cela générera des identifiants uniques. Je pense cependant que c’est un hareng rouge. J’ai créé une application de test qui vient de créer un guide après l’autre sans obtenir un seul duplicata.

Ma théorie est que l’IL a été optimisé d’une manière qui a provoqué ce comportement. Mais assez parlé de mes théories. Qu’est-ce que tu penses? Je suis ouvert aux suggestions et aux moyens de le tester.

MISE À JOUR: Il semble y avoir beaucoup de confusion dans ma question, alors laissez-moi clarifier. Je ne pense pas que NewGuid () est cassé. Clairement ça marche. C’est bien! Il y a un bogue quelque part qui fait que NewGuid () soit: 1) soit appelé une seule fois dans ma boucle 2) soit appelé à chaque fois dans ma boucle mais assigné une seule fois 3) quelque chose auquel je n’ai pas pensé

Ce bug peut être dans mon code (le plus probable) ou dans l’optimisation quelque part.

Donc, pour répéter ma question, comment dois-je déboguer ce scénario?

(et merci pour la bonne discussion, cela m’aide vraiment à clarifier le problème dans mon esprit)

MISE À JOUR # 2: J’aimerais publier un exemple qui montre le problème, mais cela fait partie de mon problème. Je ne peux pas le dupliquer en dehors de toute la suite d’applications (client et serveurs).

Voici un extrait pertinent cependant:

OrderTicket ticket = new OrderTicket(... ); for( int i = 0; i < _numOrders; i++ ) { ticket.CacheId = Guid.NewGuid(); Submit( ticket ); // note that this simply makes a remoting call } 

Submit effectue-t-il un appel asynchrone ou l’object de ticket at-il un autre thread à un autre stade?

Dans l’exemple de code, vous réutilisez le même object. Que se passe-t-il si Submit envoie le ticket dans un thread d’arrière-plan après un court délai (et ne prend pas de copie). Lorsque vous modifiez le CacheId, vous mettez à jour tous les envois en attente. Cela explique également pourquoi un Thread.Sleep résout le problème. Essaye ça:

 for( int i = 0; i < _numOrders; i++ ) { OrderTicket ticket = new OrderTicket(... ); ticket.CacheId = Guid.NewGuid(); Submit( ticket ); // note that this simply makes a remoting call } 

Si pour une raison quelconque ce n'est pas possible, essayez ceci et voyez si elles sont toujours les mêmes:

 ticket.CacheId = new Guid("00000000-0000-0000-0000-" + ssortingng.Format("{0:000000000000}", i)); 

Des milliers de développeurs utilisent des guides dans .NET. Si Guid.NewGuid () avait la moindre tendance à restr “bloqué” sur une valeur, le problème aurait été rencontré il y a longtemps.

Les changements mineurs de code sont le coupable certain. Le fait que Thread.Sleep (qui est moins un hareng rouge qu’un poisson pourrissant au soleil) “corrige” votre problème suggère que vos propriétés sont définies de manière étrange et qu’elles ne peuvent prendre effet que lorsque la boucle a cessé de se bloquer (soit en terminant ou par Thread.Sleep). Je serais même prêt à parier que le “changement mineur” était de réinitialiser toutes les propriétés à partir d’un thread séparé.

Si vous aviez posté un exemple de code, cela aiderait.

C’est un bug dans votre code. Si vous avez réussi à générer plusieurs GUID, c’est l’explication la plus probable. L’indice se trouve dans votre question: “lorsque nous avons exécuté un test après quelques modifications mineures du code dans le simulateur, tous les objects qu’il générait avaient le même Guid”

Voir cet article sur la création d’un Guid.

Cet artcile est venu de cette réponse.

En bout de ligne, si vous créez les GUID trop rapidement et que l’horloge n’a pas avancé, c’est la raison pour laquelle vous obtenez le même. Cependant, lorsque vous dormez, cela fonctionne car l’horloge a été déplacée.

Le code dans Submit et OrderTicket serait également utile …

Vous réutilisez OrderTicket. Je soupçonne que vous (ou le serveur à distance lui-même) chargez les appels en lots – probablement en ce qui concerne le nombre de connexions / limites d’hôte – et que vous récupérez la dernière valeur de CacheId lors de son envoi final.

Si vous déboguez ou que Thread.Sleep l’application, vous modifiez le minutage pour que l’appel distant se termine avant d’atsortingbuer un nouveau CacheId.

Êtes-vous en train d’appeler l’appel distant? Je penserais qu’un appel de synchronisation bloquerait – mais je vérifierais avec un renifleur de paquets comme Wireshark pour en être sûr. Quoi qu’il en soit, le simple fait de créer un nouveau OrderTicket à chaque itération ferait probablement l’affaire.

Edit: La question ne concerne pas NewGuid comme étant cassé … donc ma réponse précédente a été supprimée.

Je ne connais pas les détails de la façon dont les GUID sont générés .. pour le moment. Cependant actuellement mon org. multiplie les GUID à un rythme qui ferait honte aux lapins. Donc, je peux garantir que les GUID ne sont pas cassés .. pour le moment .

  • Publiez le code source si possible .. ou une application de reprographie clone. Plusieurs fois, je trouve que le fait de créer cette application clone pour reproduire le problème montre le problème.
  • L’autre approche consisterait à commenter «ces modifications mineures». Si cela résout le problème, vous pouvez alors sortinganguler pour trouver la ligne de code incriminée. Le globe oculaire de la mineure change fort … Je veux dire très fort.

Faites-nous savoir comment ça se passe … cela semble intéressant.

Mon instinct me dit qu’il se passe quelque chose dans ce sens …

 class OrderTicket { Guid CacheId {set {_guid = new Guid("00000000-0000-0000-0000-");} } 

Consignez la valeur de CacheId dans un fichier journal chaque fois qu’elle est appelée avec une trace de stack … Peut-être que quelqu’un d’autre la définit.