Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
844 views
in Technique[技术] by (71.8m points)

how to lock an asp.net mvc action?

I've written a controller and action that I use as a service. This service runs quite a costly action. I'd like to limit the access to this action if there is already a currently running action.

Is there any built in way to lock an asp.net mvc action?

Thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Are you looking for something like this?

public MyController : Controller
{
    private static object Lock = new object();

    public ActionResult MyAction()
    {
        lock (Lock)
        {
            // do your costly action here
        }    
    }
}

The above will prevent any other threads from executing the action if a thread is currently processing code within the lock block.

Update: here is how this works

Method code is always executed by a thread. On a heavily-loaded server, it is possible for 2 or more different threads to enter and begin executing a method in parallel. According to the question, this is what you want to prevent.

Note how the private Lock object is static. This means it is shared across all instances of your controller. So, even if there are 2 instances of this controller constructed on the heap, both of them share the same Lock object. (The object doesn't even have to be named Lock, you could name it Jerry or Samantha and it would still serve the same purpose.)

Here is what happens. Your processor can only allow 1 thread to enter a section of code at a time. Under normal circumstances, thread A could begin executing a code block, and then thread B could begin executing it. So in theory you can have 2 threads executing the same method (or any block of code) at the same time.

The lock keyword can be used to prevent this. When a thread enters a block of code wrapped in a lock section, it "picks up" the lock object (what is in parenthesis after the lock keyword, a.k.a. Lock, Jerry, or Samantha, which should be marked as a static field). For the duration of time where the locked section is being executed, it "holds onto" the lock object. When the thread exits the locked section, it "gives up" the lock object. From the time the thread picks up the lock object, until it gives up the lock object, all other threads are prevented from entering the locked section of code. In effect, they are "paused" until the currently executing thread gives up the lock object.

So thread A picks up the lock object at the beginning of your MyAction method. Before it gives up the lock object, thread B also tries to execute this method. However, it cannot pick up the lock object because it is already held by thread A. So it waits for thread A to give up the lock object. When it does, thread B then picks up the lock object and begins executing the block of code. When thread B is finished executing the block, it gives up the lock object for the next thread that is delegated to handle this method.

... but I'm not sure if this is what you are looking for...

Using this approach will not necessarily make your code run any faster. It only ensures that a block of code can only be executed by 1 thread at a time. It is usually used for concurrency reasons, not performance reasons. If you can provide more information about your specific problem in the question, there may be a better answer than this one.

Remember that the code I presented above will cause other threads to wait before executing the block. If this is not what you want, and you want the entire action to be "skipped" if it is already being executed by another thread, then use something more like Oshry's answer. You can store this info in cache, session, or any other data storage mechanism.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...