c# - 如果另一个线程已获取关键部分的锁,如何停止线程?

标签 c# multithreading

我创建了一个调度程序,它以 x 分钟的时间间隔执行一段程序。如果程序执行需要更多时间,则下一个作业不应等待当前作业完成。我正在使用 System.Timers.Timer。

_scheduler = new System.Timers.Timer(SomeMinutes);
_scheduler.Elapsed += new ElapsedEventHandler(OnTimedEvent);
_scheduler.Enabled = true;
_scheduler.AutoReset = true;

private void OnTimedEvent(object source, ElapsedEventArgs e)
{
   lock(obj)
   {
     //Critical Section
   }
}

如果我使用锁,下一个线程将等待当前线程释放锁。我不想要这种行为。如果一个线程在关键部分获取了锁对象,那么另一个线程应该退出而不执行关键部分

最佳答案

您可以使用监视器

MSDN:

The Monitor class controls access to objects by granting a lock for an object to a single thread. Object locks provide the ability to restrict access to a block of code, commonly called a critical section. While a thread owns the lock for an object, no other thread can acquire that lock. You can also use Monitor class to ensure that no other thread is allowed to access a section of application code being executed by the lock owner, unless the other thread is executing the code using a different locked object. More please...

但您可能会问,“这不是 c# 的 lock() 的作用吗?”,在某些方面是的。然而,Monitor 真正好的一点是,您可以尝试获取锁并指定超时来等待,而不是阻塞线程,直到可能的时间结束或至少直到您读完 war 与和平

此外,与Mutex不同的是,Monitor使用起来很轻量!就像 Windows 操作系统深层管道中的关键部分一样。

更改您的代码

private void OnTimedEvent(object source, ElapsedEventArgs e)
{
   lock(obj)
   {
     //Critical Section
   }
}

...至:

object _locker = new object();
const int SomeTimeout=1000;

private void OnTimedEvent(object source, ElapsedEventArgs e)
{
    if (!Monitor.TryEnter(_locker, SomeTimeout))
    {
        throw new TimeoutException("Oh darn");
    }

    try
    {
        // we have the lock so do something
    }
    finally
    {
        // must ensure to release the lock safely
        Monitor.Exit(_locker);
    }   
}

以下是 MSDN 关于 TryEnter 的说法:

Attempts, for the specified number of milliseconds, to acquire an exclusive lock on the specified object - Tell me more...

关于c# - 如果另一个线程已获取关键部分的锁,如何停止线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33139623/

相关文章:

c# - 如何检查数据类型

c# - 启动应用程序时发生错误。 InvalidOperationException : Scheme already exists: Identity. 应用程序

java - 在多线程程序线程中执行一个类的静态方法是否安全?

c++ - IUnknown.Release 标准实现竞争条件?

java - 为什么在 Java 的 Object 类中声明 wait() 和 notify()?

java - AspectJ 执行是线程安全的吗?

c# - 如何实现实现另一个接口(interface)的通用接口(interface)?

c# - 当用户在 richtextbox 中输入大量数据时显示阅读更多选项

java - C# 中的多类泛型集合

java - Android View 不能被其他线程触及?