1

我正在尝试用最佳方法将多个类处理为使用阻塞资源的方法。

目标

允许对使用DataReader. 当第一次调用正在进行时,保持其余调用(如果存在)保持直到方法结束。

当这个方法完成它的执行时,我需要丢弃在第一次执行过程中累积的每个请求,只允许最后一个请求执行。

具体来说,我正在处理一个对象中的重复事件触发,该Windows.Forms对象调用DataReader未完成执行的 a 并且它后面的下一个调用引发异常。

设计这部分的任何想法?

4

4 回答 4

3

所以你有一个事件处理程序,它会随着时间的推移反复触发。如果先前触发的处理程序仍在运行,您希望它什么也不做。这很简单,只需添加一个布尔值“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
    }
}
于 2012-10-31T20:06:14.357 回答
0

在 Java 中,您将标记该方法synchronized,一切都会好起来的。

在 C# 中,您需要做更多的工作。有关一些选项,请参阅此问题。接受的答案对我来说似乎不是最好的答案。首先尝试使用lock关键字。

于 2012-10-31T20:04:21.357 回答
0

如果R1在处理请求时收到请求R2R3并按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_requestcurrent_request应使用相同的lock.

于 2012-10-31T20:27:01.470 回答
0

最好使用 Reactive Extension 完成,只需使用 Throttle 事件触发器

于 2012-11-26T12:55:21.307 回答