[Mono-list] yield

Raja R Harinath rharinath at novell.com
Fri Sep 23 03:37:22 EDT 2005


Hi,

"Jeroen Frijters" <jeroen at sumatra.nl> writes:

> Miguel de Icaza wrote:
>> > I wanted to use yield (like Miguel did it in 
>> HttpApplication), but I need to 
>> > lock by data. Is this not allowed?
>> > 
>> > static object lockit = new Object();
>> > 
>> > public static IEnumerable GetData()
>> > {
>> >   lock (lockit)
>> >   {
>> >    for (int i = 0; i < 10; i++)
>> >     yield return true;
>> >   }
>> > }
>> > 
>> > I am getting this error (with Mono, it works with MS.Net):
>> 
>> This is a bug in the compiler.  But even with the bug fixed the code
>> above will not work in the way you think it would.
>> 
>> The lock will be taken the first time, and released on the 
>> first yield, and will not be taken again when the method resumes
>> execution (although Monitor.Exit will be called repeated times).
>
> This didn't look right to me, so I just looked at the code generated by
> the August CTP and it certainly doesn't work like you describe. Instead
> it does the "sensible" thing and acquires the lock when you first call
> MoveNext() and releases the lock when the last MoveNext() returns false,
> or when Dispose() is called.

That sounds like the right thing, since 

  lock (foo) { ... }

is essentially equivalent to:

  Monitor.Enter (foo); try { ... } finally { Monitor.Exit (foo); }

And the semantics of 'yield' inside a 'try ... finally' is to execute
the 'finally' block only on the last iteration or Dispose.

>> Basically yield and lock dont mix.
>
> That's definitely true. Even though it "works", it's still a bad idea.

&AOL;

To elaborate further on this point, and beat a dead horse:

  * 'yield' allows an arbitrary amount of code to execute.

    - It's like a 'call' in that it breaks the control flow, jumps
      elsewhere, and comes back when it's done.  

    - It's a co-call, however: unlike a normal function call, you don't
      know who's at the other end of the yield.

  * It's bad to let things you don't control to run inside your lock.

  => 'yield' and 'lock' don't mix

- Hari


More information about the Mono-list mailing list