在C#中阻止函数调用

时间:2009-12-13 18:29:03

标签: c# function locking blocking

如何在C#中阻止函数调用?

这个函数被不同的类重复调用。我想锁定它,这样在我执行当前操作之前没有其他人可以使用它。然后,我想再次发布它。

请帮助..

由于

编辑:我实际上并没有使用线程...但是我使用的是定时器,它反复调用该函数,并且它也在不同的类中调用。

5 个答案:

答案 0 :(得分:11)

使用lock

private static object lockObject = new object();

lock(lockObject) {
  // ... code goes here...
}

答案 1 :(得分:3)

如果从多个线程访问此功能,则需要某种synchronization

如果我们谈论单线程代码,为什么不使用一个布尔值来存储你的函数当前是否“可用”?

<强>更新
当你补充说你没有使用线程时,IMO只需要一个简单的bool即可 如果您需要更多状态,可以创建一个枚举并相应地设置它。

答案 2 :(得分:2)

根据您使用的计时器,您可能正在使用线程。 UI计时器(Windows.Forms.Timers)仅在UI线程上运行,因此不会重新调用它们。但是,System.Threading定时器使用线程池线程,因此可以在不同的线程上重新调用您的代码 - 在这种情况下,您需要一些线程同步(锁定)。

如果你没有使用线程,那么只有当你的代码执行某些导致自己被调用的代码时,才能重新调用你的代码。显而易见的情况是它调用自身,但不太明显的情况是应用某些操作会导致一系列事件导致您的方法再次被调用 - “反馈循环”。

所以,第一步是问“我的代码是否被重新调用?” 第二步是问“为什么?” 然后,如果你的代码导致重入,“我怎么能操作我的代码的操作,以便它不会自己调用”。
或者,如果它是线程化的,“我应该在哪里放置锁以确保一次只能有一个线程执行此代码?”

答案 3 :(得分:2)

您声明您没有使用线程。如果确实如此,那么除非你的代码块做了一些可能导致重入的事情,否则不应该多次调用该函数。

我注意到其中一个其他答案建议使用lock语句。注意,这只有在真正的问题是你从多个线程调用函数时才有效。如果问题实际上是你有一个线程但是正在做一些导致重新进入函数的事情(例如,抽取UI消息队列),那么lock语句将阻止代码多次执行 - 这是因为lock语句允许在相同的线程上进行递归锁定 - 即它只允许来自不同线程的并发访问。

因此,注意到你提到了定时器的使用,你的具体情况将取决于你使用的是哪种类型的定时器 - 如果你使用System.Threading命名空间中的定时器,那么锁可能就是你会想要(因为你实际上是在不同的线程上执行代码,因为这个计时器使用线程池来执行你的回调)。但是,如果您正在使用System.Windows.Forms命名空间中的计时器,那么您正在使用始终使用UI线程执行的计时器(通过处理UI消息队列),在这种情况下,您最有可能发生问题有某种再入问题。

如果问题是重入,并且你没有从不同的线程中调用代码,那么你应该能够只使用一个布尔变量来记录你已经在函数中的时间,而不是一个不起作用的锁。并且不允许重入。

话虽如此,如果你确实有这种类型的重入,你的设计可能会有问题。

注意,人们有时候没有考虑计时器的一件事是,当你仍在执行由先前触发计时器导致的操作时,是否可以再次触发计时器。为了避免这种情况,我个人很少设置定时器来重复触发 - 而是将其设置为仅触发一次,然后在处理响应触发器执行的操作结束时重新启用定时器 。这意味着持续时间(不调整)将成为处理上次触发操作的 end 与下一次触发操作的 start 之间的间隔。

通常这实际上是你想要的,因为你不希望在前一个操作尚未完成时触发相同的操作。

答案 4 :(得分:1)

标准方法是抛出一个InvalidOperationException,向代码的客户端发出信号,告知您的类对象尚未处于可用的状态。