Dr. Gui: Do not lock the type of object!

xiaoxiao2021-03-06  44

Do you have problems or puzzles in the Internet or Windows-based development? At this time, you can help Dr. Gui (Drgui@microsoft.com); Dr. Gui will be two guest MSDN each month, answer your questions online. Although the busy work arrangement made him unable to reply to all the questions, he will answer more questions as much as possible. If you just select your question, then doctors will send you a GUI Dr. T-shirt!

Summary: Dr. Gui explains how to avoid multithreading procedures, do not use the lock type object, although common but is wrong. (5 page print pages)

Dr. Gui's Bits and Bytes ...

... is the title of Dr. Gui Network Diary. But unfortunately, Dr. has not added more content for the column, because he went to California and Huangshi Park to take a break. But you can learn about his journey here ... and learn about some news links found recently. Alternatively, you may like to read the story ending of Alice in Blibbetland.

In short, if you have something to say, please post your comment in the comments on the same day. Or write an email for Dr. Gui ...

I hope the computer can have common sense?

Dr. Gui has recently seen a few new articles, one of which is the MIT project named Open Mind Commonsense. This item collects common sense statements for the database. Through these statements, the computer's artificial intelligence application can use common sense. You can even click on the links above, then add your common sense to the database by clicking on the link above. But Dr. Gui believes that if you can add your own common sense without prompting sentence, it will be more interesting ...

Now, step into our topic!

Why is Lock (typeof (classname) or synclock gettype (classname) is wrong

Recently, the performance designer and senior Microsoft Developer's performance designer and senior Microsoft Developer's performance designers and senior Microsoft developers communicate with Dr. Gui in an email, which is a quite common approach (unfortunately, this practice is In some of our documents, it has also been mentioned that although we will make a revision) actually there is a big problem. He asked for Dr. Gui to help publish your news and told the programmaker to use this approach. Ph.D. is of course very happy to help.

What is this very common approach? In fact, it is to lock the type object. In C #, the locking method is Lock (classname), where className is a name of a class; in Microsoft Visual Basic .NET, the locking practice is SyncLock gettype (classname).

Background Knowledge: In multi-threaded programming, the Lock / SyncLock statement is used to create a critical portion or a brief part of only one thread in the code. (If you need to update multiple fields in the object, you may need this statement - you want to make sure that other threads do not attempt to update this object at the same time!) This statement will lock the only monitoring object associated with the object you specify, if Other threads have locked the monitoring object, wait. Once it lockeds the monitoring object, any other thread cannot lock the monitoring object unless your thread is locked, the unlocking will occur automatically at the end of the closed block. One common usage is to lock this / me quote, so that only your thread can modify the object you are using - however, a better way is to lock the specific object you are about to modify. The advantage of locking as small as possible is to avoid unnecessary waiting. GetType and TypeOF returns a reference to the type object of this type. The type object of the System.Type type contains methods that enable you to reflect the type, which means you can find its fields and methods, and even access fields and call methods. Once you have a reference to the type object, you can create an instance of the object (and if you use the Type.GetType Shared / Static method, you can get a reference to the type object by name).

Therefore, the type object is very convenient. However, some programmers like "abuse" in this way, thereby replacing STATIC / Shared objects that can be locked. (Unfortunately, we mentioned this method in C # documents and Visual Basic .NET documents, this is a proposed approach.) In this case, the suggestions in these documents are wrong (we Correct). This approach is unacceptable, not to mention it.

The reason is this: Since all instances of a class have only one type object, the lock type object is equivalent to the static object contained in the lock class from the surface. As long as you lock all instances of the class, wait until you have any part of any of the other threads, then lock access, so you can securely access static members without being interfered with other threads.

This approach is indeed, at least in most cases. But it also has some questions: First, get the type object is actually a very slow process (although most programmers think this process is very fast); secondly, other threads in any class, even in the same application domain Other programs running can access this type of objects, so they may be able to lock the type object instead of you, fully block your execution, causing you to hang.

The basic problem here is that you do not have this type of object, and you don't know who can access it. In general, relying on lock is not created by you, and you don't know who can access the object is a very bad practice. This is easy to cause a deadlock. The safest way is to lock only private objects.

But in addition, there is a more serious problem. Since the type object is sometimes shared between the application domain (but not between the processes) because of the current version of the .NET runtime. (Usually there is no problem because they are constant.) This means that another application running in other application domains (but in the same process) is possible to lock the type object you want to lock, and Never release this type of object to make your application deadlock. And, this can easily obtain access rights of type objects because the object has a name - the fully qualified name of this type! Keep in mind that Lock / Synclock will have been blocking (this is a hang-in-provision) until it can be locked. Obviously, the object that relies on locking other programs or components that can be locked is not a good practice, and will cause a deadlock. This is still a bad approach even if this type of object is in your application domain, because any code can access public type type objects, resulting in deadlocks. If your components you are using in your app are not your written, this approach is particularly problematic. (Even if the Lock (this) / Synclock Me may have this problem, others may lock you. Even if this happens, the root of the problem may be more likely to find the deadlock caused by the lock type object, Because your object is not a global availability of a cross-care program domain.)

So what should I use? Very simple: as long as you declare and create an object as a lock, then use it instead of the type object to lock. Typically, in order to copy the semantics of the problem code, you will want this object to be static / shared - of course, it should be private! In short, you can code the following problem:

// C #

LOCK (TypeOf (foo)) {// bad code! no! no! NO!

// statements;

}

'VB .NET

SyncLock gettype (myclass) 'bad code! No! No! No!

'Statements

End synclock

Change to the following correct code:

// C #

Lock (someprivateStaticObject) {// good code!

// statements;

}

'VB .NET

SyncLock gettype (someprivateStaticObject) 'Good code!

'Statements

End synclock

Of course, you must already have a private static object to be locked (if you use lock to modify static objects, you may already have one!) Or you must create one. (Make it a private object to avoid other classes to lock your object.) Do not try to lock the fields that are not reference (object) types, such as int / integer. The compiler error will occur. If you don't have a private static object to be locked, you may need to create a dummy object:

// C #

Class myclass {

Private static Object omPriVateStaticObject = New Object ();

//Methods of class Go Here - Can Lock SomeprivateStaticObject

}

'VB .NET

Class myclass

Private Shared SomeprivateStaticObject As New Object 'Methods of Class Go Here - CAN Lock SomeprivateStaticObject

END CLASS

You need to analyze each case separately to ensure that there is no problem, but usually the above techniques will work.

There are two points to pay attention: First, any code other than the class cannot lock myclass.someprivateStaticObject, so many deadlocks may be avoided. Since the dead lock belongs to the most difficult problem, it may be a good thing to avoid deadlocks.

Second, you know that there is only one copy of myclass.someprivateStaticObject in your application, and each other applications running on the system also have only one copy. Therefore, there is no interaction between applications in the same application domain. Dr. Gui hopes that you can understand why the modified code is more reliable and powerful than the original problem code.

In short, don't lock the type object, because you don't know where there is a problem. The process of locking type objects is slow, and a deadlock may occur. This is a very bad program habit. Instead, you should lock static objects in the object.

Acknowledgments!

Dr. Gui is grateful here. The performance designer of the .NET running library Rico Mariani provides a valuable advice in this area.

Ask Dr. Gui

The famous problem solving expert "Dr. Gui" is very happy to provide encyclopedia knowledge in Internet and Windows-based development, making developers from all over the world. If you encounter a problem that you can't resolve, please send your questions to drgui@microsoft.com. Although the busy work arrangement made him unable to reply to all the questions, he will answer more questions as much as possible. If you just select your question, then doctors will send you a GUI Dr. T-shirt! (Note: The problem may be organized to ensure the correct syntax is correct, the logic is clear.)

Does the knowledge of Dr. Gui are not enough? Please read the GUI .NET Dr. column articles!

For other knowledge about doctors, please read the DR. Gui .Net column articles twice in the MSDN library.

Go to the original English page

转载请注明原文地址:https://www.9cbs.com/read-54903.html

New Post(0)