我正在尝试用最佳方法将多个类处理为使用阻塞资源的方法。
目标:
允许对使用DataReader
. 当第一次调用正在进行时,保持其余调用(如果存在)保持直到方法结束。
当这个方法完成它的执行时,我需要丢弃在第一次执行过程中累积的每个请求,只允许最后一个请求执行。
具体来说,我正在处理一个对象中的重复事件触发,该Windows.Forms
对象调用DataReader
未完成执行的 a 并且它后面的下一个调用引发异常。
设计这部分的任何想法?
我正在尝试用最佳方法将多个类处理为使用阻塞资源的方法。
目标:
允许对使用DataReader
. 当第一次调用正在进行时,保持其余调用(如果存在)保持直到方法结束。
当这个方法完成它的执行时,我需要丢弃在第一次执行过程中累积的每个请求,只允许最后一个请求执行。
具体来说,我正在处理一个对象中的重复事件触发,该Windows.Forms
对象调用DataReader
未完成执行的 a 并且它后面的下一个调用引发异常。
设计这部分的任何想法?
所以你有一个事件处理程序,它会随着时间的推移反复触发。如果先前触发的处理程序仍在运行,您希望它什么也不做。这很简单,只需添加一个布尔值“isRunning”作为实例字段,如果是真的什么也不做。请注意正确同步对变量的访问:
private int isRunning = 0;//there is no bool overload for `Interlocked.Exchange`
private void button1_Click(object sender, EventArgs e)
{
if (Interlocked.Exchange(ref isRunning, 1) == 0)
{
//do stuff
isRunning = 0;
}
else
{
//another handler is already in progress;
//possibly display message to user, or do nothing, or whatever
}
}
如果您不希望跳过后续事件处理程序,而只是希望它们等待并确保一次只有一个执行查询,那么您可以使用lock
:
private object key = new object();
private void button1_Click(object sender, EventArgs e)
{
lock (key)
{
//do stuff
}
}
在 Java 中,您将标记该方法synchronized
,一切都会好起来的。
在 C# 中,您需要做更多的工作。有关一些选项,请参阅此问题。接受的答案对我来说似乎不是最好的答案。首先尝试使用lock
关键字。
如果
R1
在处理请求时收到请求R2
,R3
并按R4
该顺序接收,R2
则应R3
丢弃该请求,并R4
应在处理完成后进行R
处理。
伪代码如下所示:
接收请求线程
if current_request is null
assign to current_request
else
assign to next_request
处理请求线程:
while true
if current_request is not null
process it
set current_request = next_request, next_request = null
更改next_request
并current_request
应使用相同的lock
.
最好使用 Reactive Extension 完成,只需使用 Throttle 事件触发器