Freigeben über


[MethodImpl(MethodImplOptions.Synchronized)] promised followup

OK, proof positive that even when sleep deprived I can still think :)

[MethodImpl(MethodImplOptions.Synchronized)] really is the same as using lock(this) on the whole method. I have a little test case below and I annotated the assembly... note that you can't tell anything from the IL because the IL doesn't include the locking semantics explicity, they are added by the JIT. So in summary Kit was definately correct and the PAG wording is ambiguous.

using System;
using System.Runtime.CompilerServices;

class Test
{
static void Main(String[] args)
{
Test t = new Test();
t.Go();
}

 [MethodImpl(MethodImplOptions.Synchronized)]
public virtual int Go()
{
return 1;
}
}

000000 push ESI // preserve ESI
000001 mov ESI, ECX // “this” comes in ECX, save in ESI
000003 mov ECX, ESI // dumbness :)
000005 call MONITOR_ENTER // lock ECX (“this”)
00000A mov EAX, 1 // compute exciting return code
00000F push EAX // save exciting return code
000010 mov ECX, ESI // restore ECX from ESI, “this” is back
000012 call MONITOR_EXIT // unlock “this”
000017 pop EAX // re-establish return code
000018 pop ESI // restore the saved ESI
000019 ret  // look ma, all done

Comments

  • Anonymous
    May 05, 2004
    Definitely one for either fixing the documentation, or changing the implementation. Implementing the documented behaviour would require that the CLR could create a per-method object to lock, which would be very costly (I imagine).

    I suspect that the attribute was intended to mirror Java's 'synchronized' declaration specifier (to use a C++ term, because I can't think of a clearer one right now), in which case the implementation is correct and the documentation wrong.

  • Anonymous
    July 06, 2007
    Finally it's cleaned up enough to be released, so I've put it up to Codeplex. Get the binaries

  • Anonymous
    July 06, 2007
    Finally it's cleaned up enough to be released, so I've put it up to Codeplex. Get the binaries