C# Lock syntax - 2 questions

吃可爱长大的小学妹 提交于 2019-12-18 08:56:33

问题


Can I use string as locker in the Lock ?

lock("something")

Can I do lock without braces if its only one line ?

lock("something") foo();

回答1:


1) Yes, strings are (generally) interned (by default, thanks @Eric), so any instance of the same "something" would point to the same object, therefore you'd be ok. This is very bad practice though, because someone else, in another library for example, could lock on your string, thus giving the potential for deadlocks. See here: Using string as a lock to do thread synchronization

You should do this:

private static readonly object mutex = new object();

lock(mutex)
{
    //....
}

2) Yes, same with all statements. Anything* where you have:

{
    // One line
}

could just be

// One line

*Almost anything, see @LukeH's example of the catch block, which requires the braces.




回答2:


Yes, you could use a string instance as the target of a lock. However, there are some really weird edge cases to consider.

Case 1: Literal vs. StringBuilder

In the following example the two locks will not use the same string instance. This is because the literal is interned, but the built instance is not.

string a = "something";
string b = new StringBuilder().Append("some").Append("thing").ToString();

// These are different.
lock (a)
lock (b)

However, we could manually intern the strings.

// These are the same.
lock (a)
lock (String.Intern(b))

Case 2: Version considerations

There are some differences with the way empty strings are interned from version to version.

string a = String.Empty;
string b = new StringBuilder().Append(String.Empty);

// These are the same in 1.0, 1.1, 3.5, and 4.0.
// These are different in 2.0 and 3.0.
lock (a);
lock (String.Intern(b))

Case 3: Implementation differences

Microsoft's implementation of the CLI is not the only one out there. It is conceivable that different implementations exhibit different behaviors and have their own set of caveats.

Case 4: CompilationRelaxations.NoStringInterning

Depending on whether assemblies are decorated with this and whether the CLR actually uses it (as opposed to ignoring it) may change the behavior of the interning mechanisms. This a particularly pernicious problem because it could mean that the same code behaves differently depending upon the context in which it was run.


I am sure there are other edge cases that I am unaware of. However, the point is that relying on string instances for locking purposes (or any purpose that requires implicit assumptions about the equivalence of their references) is dangerous.




回答3:


Everything George is writing is correct. One addition though. You should use braces anyway to make it perfectly clear what you want to run inside the braces. Let say you by accident write something like:

if(...)
    // one line
    // another line

when reading that you might thing that both lines will be executed inside the if block (some example uses identation to define blocks). If you instead write

if(...)
{
    // one line
}
// another line

it is perfectly clear what is run within the if block and what isn't.



来源:https://stackoverflow.com/questions/6937342/c-sharp-lock-syntax-2-questions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!