C# 多线程:如何检查静态类是否繁忙

C# 多线程:如何检查静态类是否繁忙,c#,multithreading,locking,C#,Multithreading,Locking,我有一个静态类,它有一个执行http请求的静态函数IsDataCorrect() 这个函数可以同时从多个线程调用,我想让第一个线程执行请求,其他线程应该被拒绝(这意味着它们的返回值应该为false,而不仅仅是被阻塞!),直到第一个线程完成请求后的半秒 之后,下一个获胜线程应该能够执行下一个请求,其他线程应该被拒绝,依此类推 这是我的方法,请有人确认这是否合理: static class MyClass { private static bool IsBusy = false;

我有一个静态类,它有一个执行http请求的静态函数IsDataCorrect()

这个函数可以同时从多个线程调用,我想让第一个线程执行请求,其他线程应该被拒绝(这意味着它们的返回值应该为false,而不仅仅是被阻塞!),直到第一个线程完成请求后的半秒

之后,下一个获胜线程应该能够执行下一个请求,其他线程应该被拒绝,依此类推

这是我的方法,请有人确认这是否合理:

static class MyClass
{
    private static bool IsBusy = false;

    private static object lockObject = new object();

    public static bool IsDataCorrect(string testString)
    {
        lock (lockObject)
        {
            if (IsBusy) return false;
            IsBusy = true;
        }

        var uri = $"https://something.com";

        bool htmlCheck = GetDocFromUri(uri, 2);

        var t = new Thread(WaitBeforeFree);
        t.Start();

        //Fast Evaluations
        //...           

        return htmlCheck;
    }

    private static void WaitBeforeFree()
    {
        Thread.Sleep(500);
        IsBusy = false;
    }
}

访问函数的线程仍将在access for check
IsBusy
标志中序列化,因为由于在
lockObject
上进行同步,一次只能有一个线程能够检查它。相反,您可以简单地尝试获取一个锁,因此,您不需要标志,因为锁本身将用作锁。其次,我每次都会替换启动新线程,只是为了休眠和重置标志,并用检查
DateTime
字段来替换它

static class MyClass
{
    private static DateTime NextEntry = DateTime.Now;
    private static ReaderWriterLockSlim timeLock = new ReaderWriterLockSlim();

    private static object lockObject = new object();

    public static bool IsDataCorrect(string testString)
    {
        bool tryEnterSuccess = false;
        try
        {
            try
            {
                timeLock.EnterReadLock()
                if (DateTime.Now < NextEntry) return false;
            }
            finally 
            {
                timeLock.ExitReadLock()
            }
            Monitor.TryEnter(lockObject, ref tryEnterSuccess);
            if (!tryEnterSuccess) return false;

            var uri = $"https://something.com";

            bool htmlCheck = GetDocFromUri(uri, 2);

            //Fast Evaluations
            //...           
            try
            {
                timeLock.EnterWriteLock()
                NextEntry = DateTime.Now.AddMilliseconds(500);
            } finally {
                timeLock.ExitWriteLock()
            }
            return htmlCheck;
        } finally {
            if (tryEnterSuccess) Monitor.Exit(lockObject);
        }
    }
}
静态类MyClass
{
private static DateTime NextEntry=DateTime.Now;
私有静态ReaderWriterLockSlim timeLock=新的ReaderWriterLockSlim();
私有静态对象lockObject=新对象();
公共静态bool IsDataCorrect(string testString)
{
bool-tryentersecsuccess=false;
尝试
{
尝试
{
timeLock.entereadlock()
如果(DateTime.Now

这种不启动新线程的方式更有效,DateTime访问是安全的,而且是并发的,所以线程只有在绝对必要时才会停止。否则,一切都会以最小的资源使用率继续运行。

访问函数的线程仍然会在access for check
IsBusy
标志中序列化,因为由于在
lockObject
上进行同步,一次只能有一个线程能够检查它。相反,您可以简单地尝试获取一个锁,因此,您不需要标志,因为锁本身将用作锁。其次,我每次都会替换启动新线程,只是为了休眠和重置标志,并用检查
DateTime
字段来替换它

static class MyClass
{
    private static DateTime NextEntry = DateTime.Now;
    private static ReaderWriterLockSlim timeLock = new ReaderWriterLockSlim();

    private static object lockObject = new object();

    public static bool IsDataCorrect(string testString)
    {
        bool tryEnterSuccess = false;
        try
        {
            try
            {
                timeLock.EnterReadLock()
                if (DateTime.Now < NextEntry) return false;
            }
            finally 
            {
                timeLock.ExitReadLock()
            }
            Monitor.TryEnter(lockObject, ref tryEnterSuccess);
            if (!tryEnterSuccess) return false;

            var uri = $"https://something.com";

            bool htmlCheck = GetDocFromUri(uri, 2);

            //Fast Evaluations
            //...           
            try
            {
                timeLock.EnterWriteLock()
                NextEntry = DateTime.Now.AddMilliseconds(500);
            } finally {
                timeLock.ExitWriteLock()
            }
            return htmlCheck;
        } finally {
            if (tryEnterSuccess) Monitor.Exit(lockObject);
        }
    }
}
静态类MyClass
{
private static DateTime NextEntry=DateTime.Now;
私有静态ReaderWriterLockSlim timeLock=新的ReaderWriterLockSlim();
私有静态对象lockObject=新对象();
公共静态bool IsDataCorrect(string testString)
{
bool-tryentersecsuccess=false;
尝试
{
尝试
{
timeLock.entereadlock()
如果(DateTime.Now

这种不启动新线程的方式更有效,DateTime访问是安全的,而且是并发的,所以线程只有在绝对必要时才会停止。否则,一切都会以最小的资源使用率继续进行。

我看到你们正确地解决了这个问题,但我认为仍然有空间使它同时正确、高效和简单:)。 这样怎么样

编辑:编辑以使平静更容易,并成为示例的一部分

public static class ConcurrentCoordinationExtension
{
    private static int _executing = 0;

    public static bool TryExecuteSequentially(this Action actionToExecute)
    {
        // compate _executing with zero, if zero, set 1,
        // return original value as result,
        // successfull entry then result is zero, non zero returned, then somebody is executing
        if (Interlocked.CompareExchange(ref _executing, 1, 0) != 0) return false;

        try
        {
            actionToExecute.Invoke();
            return true;
        }
        finally
        {
            Interlocked.Exchange(ref _executing, 0);//
        }
    }

    public static bool TryExecuteSequentially(this Func<bool> actionToExecute)
    {
        // compate _executing with zero, if zero, set 1,
        // return original value as result,
        // successfull entry then result is zero, non zero returned, then somebody is executing
        if (Interlocked.CompareExchange(ref _executing, 1, 0) != 0) return false;

        try
        {
            return actionToExecute.Invoke();
        }
        finally
        {
            Interlocked.Exchange(ref _executing, 0);//
        }
    }
}


class Program
{
    static void Main(string[] args)
    {
        DateTime last = DateTime.MinValue;

        Func<bool> operation= () =>
        {
            //calming condition was not meant
            if (DateTime.UtcNow - last < TimeSpan.FromMilliseconds(500)) return false;
            last = DateTime.UtcNow;
            //some stuff you want to process sequentially
            return true;
        };

        operation.TryExecuteSequentially();
    }
}
公共静态类ConcurrentCoordinationExtension
{
私有静态int_=0;
公共静态布尔操作依次执行(此操作操作执行)
{
//compat_执行时为零,如果为零,则设置为1,
//返回原始值作为结果,
//成功输入然后结果为零,返回非零,然后有人正在执行
if(interlocated.compareeexchange(ref _executing,1,0)!=0)返回false;
尝试
{
actionToExecute.Invoke();
返回true;
}
最后
{
联锁交换(参考执行,0)//
}
}
公共静态布尔函数依次执行(此函数操作执行)
{
//compat_执行时为零,如果为零,则设置为1,
//返回原始值作为结果,
//成功输入然后结果为零,返回非零,然后有人正在执行
if(interlocated.compareeexchange(ref _executing,1,0)!=0)返回false;
尝试
{
return actionToExecute.Invoke();
}
最后
{
联锁交换(参考执行,0)//
}
}
}
班级计划
{
静态void Main(字符串[]参数)
{