[英]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.