简体   繁体   English

在同步结构(例如ManualResetEvent)上等待的可更新(可重置)超时

[英]Updateable (resetable) timeout of Wait on a synchronization construction such as ManualResetEvent

Here is the description of the problem: 这是问题的描述:

I need to make an API call synchronized. 我需要使API调用同步。 In order to make this call synchronized, I defined a ManualResetEvent and called WaitOne on it. 为了使此调用同步,我定义了ManualResetEvent并对其调用了WaitOne。 WaitOne is called after the call to external COM object. 调用外部COM对象后,将调用WaitOne。 In some circumstances it never returns. 在某些情况下,它永远不会返回。 That's why I must define a timeout for that Wait call. 这就是为什么我必须为该Wait调用定义超时的原因。 But, I can't pass a constant into Wait method, because if the call was successfull than this API receives events from the COM object and in each handler of an event, timeout passed into WaitOne should be reset. 但是,我无法将常量传递给Wait方法,因为如果调用成功,则此API将从COM对象接收事件,并且在事件的每个处理程序中,应重置传递给WaitOne的超时。

Consider the example: 考虑示例:

private ManualResetEvent operationIsInProcess;
private static readonly IComObject sender;
private int timeout = 30000;

public void Start() {                           
    sender.OnExchange += SenderOnOnExchange;            
}
private void StartOperation(){
    sender.StartAsyncExchange();
    operationIsInProcess.WaitOne(timeout);
}

private void SenderOnOnExchange(){
    //somehow we need to reset or update that timeout on WaitOne
    //operationInProcess.Update(timeout);
}

I'm just wondering whether anybody faced this problem or not. 我只是想知道是否有人遇到过这个问题。 I'm sure this should be a common situation. 我相信这应该是一种普遍情况。 As I understand there is no "out of the box" solution. 据我了解,没有“开箱即用”的解决方案。 So I have to build my own syncronization primitive, or maybe someone have already done it? 所以我必须构建自己的同步原语,或者也许有人已经做到了?

Update. 更新。 I wanted something like this (implemented by myself): 我想要这样的东西(由我自己实现):

public class UpdateableSpin {
        private readonly object lockObj = new object();
        private bool shouldWait;
        private long taskExecutionStartingTime;

        public UpdateableSpin(bool initialState) {
            shouldWait = initialState;
        }

        public void Wait(TimeSpan executionTimeout, int spinDuration = 0) {
            UpdateTimeout();
            while (shouldWait && DateTime.UtcNow.Ticks - taskExecutionStartingTime < executionTimeout.Ticks) {
                lock (lockObj) {
                    Thread.Sleep(spinDuration);
                }
            }
        }

        public void UpdateTimeout() {
            lock (lockObj) {
                taskExecutionStartingTime = DateTime.UtcNow.Ticks;
            }
        }

        public void Reset() {
            lock (lockObj) {
                shouldWait = true;
            }
        }

        public void Set() {
            lock (lockObj) {
                shouldWait = false;
            }
        }
    }

You could enter a loop and restart the wait: 您可以进入循环并重新开始等待:

while (true)
{
    if (!operationIsInProcess.WaitOne(timeout))
    {
        // timed out 
        break;
    }
    else
    {
        // Reset the signal.
        operationIsInProcess.Reset();
    }
}

Then set your event in the event handler. 然后在事件处理程序中设置事件。

private void SenderOnOnExchange () 
{
    operationInProcess.Set();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Thread.Sleep(timeout)和ManualResetEvent.Wait(timeout)有什么区别? - What is the difference between Thread.Sleep(timeout) and ManualResetEvent.Wait(timeout)? WaitOne()不会在ManualResetEvent中等待 - WaitOne() doesnot wait in ManualResetEvent 使用ManualResetEvent在内部等待 - Wait inside While with ManualResetEvent ManualResetEvent在处于等待状态时会消耗cpu吗? - Will the ManualResetEvent consume cpu while it is in a wait state? ManualResetEvent.WaitOne()返回false而不超时? - ManualResetEvent.WaitOne() returning false without timeout? 如何继续前进之前等待ManualResetEvent.WaitOne()到达? - How to wait for ManualResetEvent.WaitOne() to be reached before moving on? 使用ManualResetEvent等待多个Image.ImageOpened事件 - Using ManualResetEvent to wait for multiple Image.ImageOpened events 使用 ManualResetEventSlim 而不是 ManualResetEvent 的最短等待时间是多少? - What is the minimum wait time to use ManualResetEventSlim instead of ManualResetEvent? ManualResetEvent(EventWaitHandle)Set花费的CPU比WaitOne(超时)大得多 - ManualResetEvent(EventWaitHandle) Set spends much cpu than WaitOne(timeout) 设置后,ManualResetEvent等待不会释放 - ManualResetEvent wait doesn't release after being set
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM