开发者

Locking hierarchy of objects in .NET

I have a class that represents the "state of the world". The class has many collections of many other objects which in turn have references to more objects and collections of objects, sometimes even references to their ancestors in the "world hierarchy". To simplify what's being said, here is an example (transformed into XML, details omitted):

<World>
<Country>
    <City>
        <Block>
        ...
        </Block>
    </City>
    <City>
        <Block>
        ...
        </Block>
    </City>
</Country>
...
<Country>
    <City>
        <Block> ... </Block>
        ...
        <Block> ... </Block>
    </City>
    <City>
        <Block> ... </Block>
    </City>
</Country>
</World>

There are two threads, the UI thread and the background thread (whic开发者_运维问答h is actually a server).

The server receives the messages which modify the "state of the world" (adding cities, blocks etc.).

The UI thread draws the world's state to screen using PictureBox object every once in a while. The presentation layer has only reference to the IWorld object (which World implements), and it has no way to access the elements within.

The UI thread should lock the complete state of the world so the world can't be changed (by the server) during the drawing (that would make an inconsistent world picture). Since it has only reference to the IWorld object, this is the only thing to be locked.

My question is whether this lock would suffice (that is, lock all fields and properties this object has, recursively), or each object should be locked separately. What is the right approach to this problem?

Note: UI has no way to contact server (meaning it can't tell server to stop changing the world, and then tell it to resume after rendering).

EDIT: If the World and all classes in hierachy implement ILock interface which provides Lock() method which would call Lock() on all lower levels (recursively), this would probably be prone to deadlock (cyclic references) or simply be too expensive.

I guess design change is in order.


You don't need to lock recursively - if both threads just lock on the same IWorld reference, that will be enough to assure mutual exclusivity.

Locking on the individual elements would give you finer grained locking of course, but then you could end up with an inconsistent picture - I would imagine that you'd want to see a whole set of changes from the server at a time.

However, a better model would usually be to make the server publish "snapshots" and then create a new copy of the world and modify the copy, turning it into a snapshot when appropriate. That way you don't need this mutual exclusion which could block your UI when it wants to draw the world while the server is changing it.


The main question is how you access the elements below the world. If everything is accessed via a "World singleton", then a global lock is fine and safe.
If you access the countries, cities, etc... directly, then you need individual locks which need to be requested in the exact same order if you need to change several parts of the chain the same time.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜