在 C# 中阻止函数调用
如何在 C# 中阻止函数调用?
该函数被不同的类重复调用。我想将其锁定,以便在我执行当前操作之前没有其他人可以使用它。然后,我想再次发布它。
请帮忙..
谢谢
编辑:我实际上并没有使用线程...但我使用的是重复调用该函数的计时器,并且它也在不同的类之间调用。
How do I block a function call in C#?
This function gets repeatedly called by different classes.I want to lock it up so that no one else can use it until I perform my current operation. Then,i want to release it again.
Please help..
Thanks
Edit:I'm not actually using threads...but I am using timers that call the function repeatedly and it's also called among different classes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用
锁
:Use a
lock
:如果您从多个线程访问此函数,则需要某种同步。
如果我们谈论的是单线程代码,为什么不直接使用一个布尔值来存储您的函数当前是否“可用”?
更新:
正如您所补充的,您没有使用线程,IMO 一个简单的 bool 就足够了。
如果您需要更多状态,您可以创建一个枚举并进行相应的设置。
If you are accessing this function from multiple threads you need some sort of synchronization.
If we are talking about single-threaded code, why not just use a boolean that stores if your function is currently "usable"?
Update:
As you added that you are not using threads, IMO a simple bool would suffice.
If you need more states, you could create an enum and set that accordingly.
根据您使用的计时器,您可能会使用线程。 UI 计时器 (Windows.Forms.Timers) 仅在 UI 线程上运行,因此不会被重入调用。但是,System.Threading 计时器使用线程池线程,因此可以在不同线程上重入调用您的代码 - 在这种情况下,您需要一些线程同步(锁)。
如果您不使用线程,那么您的代码只能在执行导致自身被调用的操作时才能被重入调用。最明显的情况是当它调用自身时,但不太明显的是应用某些操作导致一系列事件导致您的方法被再次调用的情况 - “反馈循环”。
所以,第一步是问“我的代码是否被可重入调用?”
第二步是问“为什么?”
然后,如果您的代码导致重入,“我如何更改代码的操作,使其不会调用自身”。
或者,如果它是线程化的,“我应该在哪里放置锁以确保一次只有一个线程可以执行此代码?”
Depending on the timers you use, you may be using threads. UI timers (Windows.Forms.Timers) only run on the UI thread, so they will not be called reentrantly. However, System.Threading timers use threadpool threads, so your code can be called reentrantly on different threads - in which case you need some thread synchronisation (locks).
If you are not using threads, then your code can only be called re-entrantly if it does somethng that causes itself to be called. The obvious case is when it calls itself, but less obvious are cases where applying some action causes a chain of events that result in your method being called again - a "feedback loop".
So, the first step is to ask "is my code being called reentrantly?"
The second step is to ask "why?"
Then, if your code is causing the reentrancy, "how can I chnage the operaiton of my code so it doesn't call itself".
Or, if it's threaded, "where should I put locks to ensure that only one thread can execute this code at a time?"
您声明您没有使用线程。如果确实如此,那么该函数不应该被多次调用,除非您的代码块执行了可能导致重入的操作。
我注意到这里的其他答案之一建议使用 lock 语句。请注意,只有当真正的问题是您从多个线程调用该函数时,这才有效。如果问题实际上是您有一个线程,但正在执行一些导致重新进入函数的操作(例如泵送 UI 消息队列),那么锁定语句将不会阻止代码多次执行 -这是因为 lock 语句允许在同一线程上进行递归锁定 - 即它只不允许不同线程的并发访问。
因此,注意到您提到了计时器的使用,您的具体情况将取决于您使用的计时器类型 - 如果您使用的是 System.Threading 命名空间中的计时器,那么锁可能就是您想要的(因为您实际上是在不同的线程上执行代码,因为该计时器使用线程池来执行回调)。但是,如果您使用的是 System.Windows.Forms 命名空间中的计时器,那么您使用的计时器始终使用 UI 线程执行(通过处理 UI 消息队列),在这种情况下,最有可能出现的问题是您存在某种可重入问题。
如果问题是重入,并且您没有从不同的线程调用代码,那么您应该能够使用布尔变量来记录您何时已经在函数中,并禁止重入,而不是使用不起作用的锁。
话虽如此,如果您确实有这种类型的重入,您的设计可能会出现问题。
请注意,对于计时器,人们有时没有考虑到的一件事是,当您仍在执行先前触发计时器所产生的操作时,是否可以再次触发计时器。为了避免这种情况,我个人很少将计时器设置为重复触发 - 相反,我将其设置为仅触发一次,然后在处理响应触发而执行的操作结束时重新启用计时器 。这意味着持续时间(无需调整)成为处理上一个触发操作的结束和下一个触发操作的开始之间的间隔。
通常,这实际上是您想要的,因为您不希望在上一个操作尚未完成时触发相同的操作。
You state that you are not using threads. If this is really the case, then it should not be possible for the function to be called multiple times unless your block of code does something which can causes reentrancy.
I notice one of the other answers here suggests using the lock statement. Note, this will only work if the real issue is that you are calling the function from multiple threads. If the issue is actually that you have a single thread but are doing something which results in reentering the function (e.g. pumping the UI message queue) then the lock statement will not prevent the code from executing multiple times - this is because the lock statement allows recursive locks on the same thread - i.e. it only disallows concurrent access from different threads.
So, noticing that you mention the use of timers, your particular situation is going to depend on which type of timers you are using - if you are using the timer from the System.Threading namespace, then the lock is probably what you will want (because you actually are executing the code on different threads since this timer uses the thread pool to execute your callbacks). If however, you are using the timers from the System.Windows.Forms namespace, then you are using a timer that always executes using the UI thread (via processing the UI message queue), and in this case it's most likely that the issue you have is some kind of reentrancy issue.
If the issue is reentrancy, and you are not calling the code from different threads then instead of a lock which won't work, you should be able to just use a boolean variable to record when you are already in the function, and disallow reentrancy.
Having said that, if you do have this type of reentrancy you may have a problem with your design.
Note, one thing with timers people sometimes fail to take into account is whether it is ok for the timer to be triggered again whilst you are still performing operations resulting from a previous triggering of the timer. In order to avoid this, I personally rarely set a timer to trigger repetitively - instead I set it to trigger once only, and then reenable the timer at the end of processing the operations performed in response to the trigger. This means that the time duration (without adjustment) becomes the interval between the end of processing the last triggered operation and the start of the next triggered operation.
Usually though this is actually what you want since you don't want the same operation to be triggered while the previous operation has not yet completed.
标准方法是抛出 InvalidOperationException,向代码的客户端发出信号,表明您的类对象尚未处于可用状态。
The standard way to do is to throw an InvalidOperationException, signaling the client of your code that your class object is not yet in a state to be usable.