Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using lock() for collection in ToString() method

Tags:

I've faced myself in a situation, when my overridden ToString() method would use one of the instance's collections.

public override string ToString()
{
    string returnStr = "testString";

    lock (_sync)
    {
        returnStr = $"{returnStr}: {string.Join(",", _testList)}";  // where _testList is a List<string> in the class's scope
    }

    return returnStr;
}

Since we are talking about a multi-threaded application, I was wondering, since I would have to use lock() inside the ToString() method's body in order to avoid the collection's modification while my return string is being generated. While I'm doing modifications on the collection, the same object (_sync) is being locked, of course.
But, this method is being used by several other processes as well, such as the Visual Studio's Debugger and who knows what else, since this method is being inherited from the Object class itself.
For example: I fear that it might being called more often behind the scene (by the framework or anything else), and would have to use the locking (which could lead to performance loss), or it might cause deadlock while I'm debugging in a bad moment.

Question:
Should I care about this situation, since it could cause problems, or is it OK to use object locking inside ToString() (and in other inherited methods from .net types)?

Are there any better alternative solutions in order to achieve this same goal?

Note: I was thinking about to generate the required string from the collection every time when that is being modified (inside the lock, where it is being manipulated), so I would have the collection's string format ready to be concatenated in the ToString() method itself. I guess it would be even better for performance, since the process of string.Join() wouldn't have to run at every call of ToString(), but I'm really curious to know more about this situation.

Thanks!

like image 963
aniski Avatar asked May 25 '16 12:05

aniski


People also ask

Why should you override the toString () method?

When you create a custom class or struct, you should override the ToString method in order to provide information about your type to client code. For information about how to use format strings and other types of custom formatting with the ToString method, see Formatting Types.

What happens if you call toString on a String?

The toString() method returns a string representing the specified string value.

Can a toString method be void?

No, because if you want to call toString method like ClassName.

What is lock in C#?

The lock statement acquires the mutual-exclusion lock for a given object, executes a statement block, and then releases the lock. While a lock is held, the thread that holds the lock can again acquire and release the lock. Any other thread is blocked from acquiring the lock and waits until the lock is released.


1 Answers

Do you really need/use the ToString() that often? Your scenario seems more of a business logic and I wouldn't mix it up with the ToString() implementation.

I would go for something like: GetSnapshotRepresentation() that uses locks and the whole conundrum and leave ToString() returning something very lightweight (e.g. id, type, something immutable, etc.)

Putting locks and that heavy machinery into ToString() you will block your writers if you make calls to ToString() that you didn't want/needed to do.

like image 153
Tamas Ionut Avatar answered Sep 28 '22 03:09

Tamas Ionut