The workaround in the link above does, in the strictest sense, address this issue. Invocation lists are immutable. If a separate thread were to remove a handler from the original invocation list while the publisher (OnEvent...) was executing this would create a new Invocation list (one without the removed handler) while the publisher would continue using it's copied reference to the original.
Unfortunately this may not address the underlying issue: while an event is being published its list of handlers should not be modified. C# provides a way to deal with this via event accessors. By combining event accessors and basic synchronization (via lock), it's possible to make a truly thread-safe event invocation pattern:
public class EventSource
{
private EventHandler testEventHandlers;
public event EventHandler TestEvent
{
add
{
lock (testEventHandlers) { testEventHandlers += value; }
}
remove
{
lock (testEventHandlers) { testEventHandlers -= value; }
}
}
public void OnTestEvent()
{
lock (testEventHandlers)
{
if (testEventHandlers != null)
testEventHandlers(this, new EventArgs());
}
}
}
No comments:
Post a Comment