Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何向ASP.NET web应用程序添加全局锁?_C#_Asp.net_Locking - Fatal编程技术网

C# 如何向ASP.NET web应用程序添加全局锁?

C# 如何向ASP.NET web应用程序添加全局锁?,c#,asp.net,locking,C#,Asp.net,Locking,我正在使用C编写一个ASP.NET web应用程序,它可以从IIS服务器读取和写入文本文件(使用System.IO.FileStream),我想知道如何在此操作上实现全局锁?获取所需的全局锁 最简单的解决方案是在缓存或应用程序对象中创建一个新对象,最好是在global.asax文件中的应用程序启动中。例如: Cache["myLocker"] = new object(); 然后可以使用标准的“锁定”语法 根据@Aristos的建议,我提出了这门课: using System.Threadin

我正在使用C编写一个ASP.NET web应用程序,它可以从IIS服务器读取和写入文本文件(使用
System.IO.FileStream
),我想知道如何在此操作上实现全局锁?

获取所需的全局锁


最简单的解决方案是在缓存或应用程序对象中创建一个新对象,最好是在global.asax文件中的应用程序启动中。例如:

Cache["myLocker"] = new object();
然后可以使用标准的“锁定”语法


根据@Aristos的建议,我提出了这门课:

using System.Threading;
using System.Security.AccessControl;
using System.Security.Principal;

using System.Runtime.InteropServices;   //GuidAttribute
using System.Reflection;                //Assembly

namespace ITXClimateSaverWebApp
{
    public class GlobalNamedLock
    {
        private Mutex mtx;

        public GlobalNamedLock(string strLockName)
        {
        //Name must be provided!
            if(string.IsNullOrWhiteSpace(strLockName))
            {
                //Use default name
                strLockName = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();
            }

            //Create security permissions for everyone
            //It is needed in case the mutex is used by a process with
            //different set of privileges than the one that created it
            //Setting it will avoid access_denied errors.
            MutexSecurity mSec = new MutexSecurity();
            mSec.AddAccessRule(new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                MutexRights.FullControl, AccessControlType.Allow));

            //Create the global mutex
            bool bCreatedNew;
            mtx = new Mutex(false, @"Global\" + strLockName, out bCreatedNew, mSec);
        }

        public bool enterCRITICAL_SECTION()
        {
            //Enter critical section
            //INFO: May throw an exception!
            //RETURN:
            //      = 'true' if successfully entered
            //      = 'false' if failed (DO NOT continue!)

            //Wait
            return mtx.WaitOne();
        }

        public void leaveCRITICAL_SECTION()
        {
            //Leave critical section
            //INFO: May throw an exception!

            //Release it
            mtx.ReleaseMutex();
        }
    }
}
然后是调用全局锁的方法:

try
{
    GlobalNamedLock gl = new GlobalNamedLock("MyLockName");

    try
    {
        if (gl.enterCRITICAL_SECTION())
        {
            //Use the global resource now
        }
    }
    finally
    {
        gl.leaveCRITICAL_SECTION();
    }
}
catch (Exception ex)
{
    //Failed -- log it
}

因此,这似乎起到了作用。你怎么看?

为什么不直接使用全局同步根对象

internal static class Lock
{
    public static object SyncRoot = new object{};
}
用法:

lock (Lock.SyncRoot)
{
}

命名互斥体是系统对象。与锁定关键字不同,它们甚至可以跨流程边界工作。锁定仅在同步同一进程中的线程时有用。

谢谢。后续问题。我是否必须将“key”变量中的互斥体名称设置为
Global\key
,才能在全局范围内读取它?@c0000fd该键,无论名称是什么,对计算机来说都是全局的。确定。我基于WinAPI命名的互斥体(我相信这是“内部的”)。请阅读
lpName
参数的说明:@c0000fd我不明白您的意思。你能直接说出你的观点吗?检查这一点:我建议使用其他名称,而不是
enterCRITICAL\u SECTION
leaveCRITICAL\u SECTION
。它们在我所能想象到的任何编程语言中都是完全不可接受的。main的许多代码比内置的带C#的“lock”关键字更复杂。@CyanLite:对不起,什么?@c0000fd:你写的东西和“lock”关键字写的东西完全一样。@CyanLite:如果我知道的话,我不会写的。顺便问一下,你怎么知道的?
首先想到的是应用程序
。但有一次我被告知,我喜欢这样的想法,这个类是为经典的ASP兼容性而提供的,实际上你不需要它,因为你可以使用静态类,而静态类的速度要快得多。是不是因为这个静态锁实际上不适用于多个工作进程?这个答案实际上是错误的,而且在有多个工作进程的情况下不起作用。@Ahmad:这个问题没有提到“多个工作进程”,基本上也没有提到所有其他答案。那么你到底在说什么呢?@abatishchev这是在说一个全局锁,而你提供的方式在某些情况下并不能做到这一点,这种情况并不罕见。这就是我的观点。@Ahmad:上面哪一个答案适用于多个工作进程?
internal static class Lock
{
    public static object SyncRoot = new object{};
}
lock (Lock.SyncRoot)
{
}