tags:

views:

152

answers:

1

should I lock event in the following case:

event foo;

thread A: will call foo += handler;

thread B: will call foo -= handler;

should I lock foo?

+10  A: 

Locking on foo is a bad idea, because the value will change each time. You should lock on a variable which doesn't change:

private readonly object eventLock = new object();
private EventHandler fooHandler;

public event EventHandler Foo
{
    add
    {
        lock (eventLock)
        {
            fooHandler += value;
        }
    }
    remove
    {
        lock (eventLock)
        {
            fooHandler -= value;
        }
    }
}

private void OnFoo(EventArgs e)
{
    EventHandler handler;
    lock (eventLock)
    {
        handler = fooHandler;
    }
    if (handler != null)
    {
        handler(this, e);
    }
}

Note that if you use a field-like event, like this:

public event EventHandler Foo;

then you'll automatically get a "lock(this)" on add/remove, although you'd have to manually add it when fetching the handler before calling it (assuming you want to make sure you read the most recently written value). Personally I'm not a fan of locking on "this", but you may not mind - and it certainly makes for simpler code.

Jon Skeet
thanks. got you.
Benny
I've got an edit coming when my netbook gets a 3g signal again.
Jon Skeet
@Jon, I am using a field-like event, so i don't need to lock on add/remove, am i right?
Benny
@Jon, i am calling the event handler using the event directly, like this foo(), not fetching the handler out of the event, should i add lock?
Benny
@Benny: If you're using a field-like event you don't *have* an add/remove to lock on. If you're calling the event handler directly, how are you guarding against it being null? Note that you can't just use `if (foo != null) { foo(...); }` as `foo` could *become* null after the test. Also it wouldn't guarantee that you'd get the latest value - that's why I've got the locking in my `OnFoo` method. (Memory models can do funny things...)
Jon Skeet
Note that the codegen for field-like events will be changing in C# 4 to address the "lock this" code smell. Chris Burrows will be writing a blog about that some time in the next few months; watch his blog for details.
Eric Lippert