M
Martin Carpella
Hello everyone,
I experience some strange behaviour of anoynmous delegates which refer
to variables outside the scope of the delegate.
Please have a look at the following code and output at the end of this
post and tell me, if the observed behaviour is intentionally or if it is
a bug.
The problem ist the output in the first foreach loop. It seems, that
every created delegate is executed with the _last_ value of val instead
of the value of val when the delgate is created.
As you can see in the output below, in the second foreach where the
delegate is created in its own method, the behaviour is as I expected it
to be.
Did I misunderstand the following part of the documentation?
| Unlike local variables, the lifetime of the outer variable extends until
| the delegates that reference the anonymous methods are eligible for
| garbage collection. A reference to n is captured at the time the
| delegate is created.
Does this really mean, that a reference to the variable is captured and
not a reference to the value? Why then does it work when putting the
delegate creation in its own method?
Please, could anyone comment on this?
Best regards,
Martin Carpella
class Program {
static void Main(string[] args) {
object semaphore = new object();
lock (semaphore) {
string[] values = new string[] { "a", "b", "c" };
foreach (string val in values) {
ThreadPool.QueueUserWorkItem(delegate(object state)
{
lock (semaphore) {
Console.Out.WriteLine("Pool (1): " + val);
} // lock
});
Console.Out.WriteLine("Main (1): " + val);
} // foreach
foreach (string val in values) {
QueueItem(semaphore, val);
Console.Out.WriteLine("Main (2): " + val);
} // foreach
} // foreach
}
private static void QueueItem(object semaphore, string val) {
ThreadPool.QueueUserWorkItem(delegate(object state) {
lock (semaphore) {
Console.Out.WriteLine("Pool (2): " + val);
} // lock
});
}
}
The strange thing is the output:
Main (1): a
Main (1): b
Main (1): c
Main (2): a
Main (2): b
Main (2): c
Pool (1): c
Pool (1): c
Pool (1): c
Pool (2): a
Pool (2): b
Pool (2): c
I experience some strange behaviour of anoynmous delegates which refer
to variables outside the scope of the delegate.
Please have a look at the following code and output at the end of this
post and tell me, if the observed behaviour is intentionally or if it is
a bug.
The problem ist the output in the first foreach loop. It seems, that
every created delegate is executed with the _last_ value of val instead
of the value of val when the delgate is created.
As you can see in the output below, in the second foreach where the
delegate is created in its own method, the behaviour is as I expected it
to be.
Did I misunderstand the following part of the documentation?
| Unlike local variables, the lifetime of the outer variable extends until
| the delegates that reference the anonymous methods are eligible for
| garbage collection. A reference to n is captured at the time the
| delegate is created.
Does this really mean, that a reference to the variable is captured and
not a reference to the value? Why then does it work when putting the
delegate creation in its own method?
Please, could anyone comment on this?
Best regards,
Martin Carpella
class Program {
static void Main(string[] args) {
object semaphore = new object();
lock (semaphore) {
string[] values = new string[] { "a", "b", "c" };
foreach (string val in values) {
ThreadPool.QueueUserWorkItem(delegate(object state)
{
lock (semaphore) {
Console.Out.WriteLine("Pool (1): " + val);
} // lock
});
Console.Out.WriteLine("Main (1): " + val);
} // foreach
foreach (string val in values) {
QueueItem(semaphore, val);
Console.Out.WriteLine("Main (2): " + val);
} // foreach
} // foreach
}
private static void QueueItem(object semaphore, string val) {
ThreadPool.QueueUserWorkItem(delegate(object state) {
lock (semaphore) {
Console.Out.WriteLine("Pool (2): " + val);
} // lock
});
}
}
The strange thing is the output:
Main (1): a
Main (1): b
Main (1): c
Main (2): a
Main (2): b
Main (2): c
Pool (1): c
Pool (1): c
Pool (1): c
Pool (2): a
Pool (2): b
Pool (2): c