Pour voir truely s'il y a un moyen plus simple à mettre en œuvre Monitor.Wait
, nous avions AHVE d'enquêter sur la façon dont il fonctionne à un niveau bas. L'implémentation réelle est finalement écrite en C et cachée chez nous mais spécifiquement pour Monitor.Wait(object)
, nous pouvons tracer la chaîne d'appels de la manière suivante; De là, il est plus difficile de voir ce qui se passe même dans ILSpy. Selon le lien de Tigran à la source de l'objet Monitor
, il nous reste ce qui suit dans la source;
/*========================================================================
** Waits for notification from the object (via a Pulse/PulseAll).
** timeout indicates how long to wait before the method returns.
** This method acquires the monitor waithandle for the object
** If this thread holds the monitor lock for the object, it releases it.
** On exit from the method, it obtains the monitor lock back.
** If exitContext is true then the synchronization domain for the context
** (if in a synchronized context) is exited before the wait and reacquired
**
** Exceptions: ArgumentNullException if object is null.
========================================================================*/
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool ObjWait(bool exitContext, int millisecondsTimeout, Object obj)
La description est laissée assez auto-explanitory dans ce qui est qu'il fait et dans quel ordre. Cependant, la mise en œuvre précise par laquelle il le fait est enveloppée de diverses méthodes qui contiennent le code crucial.
extern
specifies que l'implémentation réelle réside dans un autre assembly. Il peut être utilisé avec DllImport
lors de l'accès au code non géré (pas le cas ici) ou peut être un extern alias. D'ici, comme SO poster asking about where to find the implementation of extern methods, vous auriez à regarder le code C lui-même qui peut être trouvé dans le Core CLR (crédit Scott Chamberlain). De là, nous examinons l'implémentation de la méthode C pour ObjWait()
qui maps (ligne 1027) à ObjectNative::WaitTimeout
dans le CLR;
FCIMPL3(FC_BOOL_RET, ObjectNative::WaitTimeout, CLR_BOOL exitContext, INT32 Timeout, Object* pThisUNSAFE)
{
FCALL_CONTRACT;
BOOL retVal = FALSE;
OBJECTREF pThis = (OBJECTREF) pThisUNSAFE;
HELPER_METHOD_FRAME_BEGIN_RET_1(pThis);
if (pThis == NULL)
COMPlusThrow(kNullReferenceException, W("NullReference_This"));
if ((Timeout < 0) && (Timeout != INFINITE_TIMEOUT))
COMPlusThrowArgumentOutOfRange(W("millisecondsTimeout"), W("ArgumentOutOfRange_NeedNonNegNum"));
retVal = pThis->Wait(Timeout, exitContext);
HELPER_METHOD_FRAME_END();
FC_RETURN_BOOL(retVal);
}
FCIMPLEND
Avant d'entrer dans cela, il vaut la peine de regarder this (crédit aussi Scott Chamberlain), qui stipule; Les appels sont identifiés dans le code managé en tant que méthodes extern avec le jeu de bits MethodImplOptions.InternalCall. Cela explique notre lien vers ObjWait()
et ObjectNative::WaitTimeout
. Donc, en décomposant plus loin, nous pouvons voir null
de base et des vérifications d'arguments avec des exceptions appropriées soulevées si c'est le cas. Le crux est l'appel à pThis->Wait()
... à quel point je ne peux pas tout à fait tracer plus loin ... encore.
De là, nous arrivons à Object::Wait
(line 531), puis aller à SyncBlock::Wait
(line 3442).À ce stade, nous avons l'essentiel de la mise en œuvre et il y en a beaucoup.
Compte tenu de tout ce qui précède et de revenir à ce que vous avez demandé une implémentation plus simple, je serais prudent de simplifier Monitor.Wait()
. Il y a un lot qui se passe sous le capot et il serait très facile de faire une erreur et d'avoir des bugs potentiels dans une implémentation alternative.
EDIT
cri grave vers Scott Chamberlain qui a fait la majeure partie de l'enquête ci-dessous ILSpy niveau et Fouille/débogage la pile de code C. À peu près tout le travail d'enquête au-dessous du niveau d'ILSpy est le sien, je l'ai simplement compilé ici dans une réponse.
[System.Threading.Monitor] (http://referencesource.microsoft.com/#mscorlib/system/threading/monitor.cs) – Tigran
L'article associé à votre question répond efficacement à ce que je peux dire. Quelles informations supplémentaires recherchez-vous? – DiskJunky
Afin de mieux comprendre la fonction d'attente, j'étais curieux de savoir s'il est possible de le ré-implémenter en tant que fonction simple en utilisant ce qui est déjà donné comme une API .Net publiée. C'est plus facile à comprendre que de code ... –