开发者

How can avoid at this line an OverflowException?

LastInput.time is an Integer and m_idleTime is an Integer too. This line sometimes generates an Overflow exception, I think that this happens when both values are big negative values.

(Environment.TickCount - lastInput.time) > m_idleTime

How can I avoid that? With casting?

开发者_如何学Python(CType(Environment.TickCount,Long) - CType(lastInput.time,Long)) > m_idleTime

Or maybe with this cast?

CType((Environment.TickCount - lastInput.time),Long) > m_idleTime

Thanks in advance.

EDIT: I'm using the GetLastInputInfo method to check how many time has been the computer idle. I have declared the return value from the call this way:

    <StructLayout(LayoutKind.Sequential)> Public Structure StructLastInputInfo
        <MarshalAs(UnmanagedType.U4)> Dim size As Integer
        <MarshalAs(UnmanagedType.U4)> Dim time As Integer
    End Structure

So I think that when the Environment.TickCount returns a negative value the same will happen with the GetLastInputInfo, right? But then the values of the substraction will be wrong because they will be negative, so as far as I see the problem what should be done is this:

Math.Abs(CType(Environment.TickCount, Long) - CType(lastInput.time, Long)) > m_idleTime

What do you think?


Assuming the problem is as you described, you need the first of those options:

(CType(Environment.TickCount,Long) - CType(lastInput.time,Long)) > m_idleTime

The second will fail before it converts to Long, because the conversion is done after the calculation.

But I would think that you shouldn't have large negative values in this calculation. Note that after 24.9 days, Environment.TickCount overflows and becomes negative. Maybe this is what is happening? If so, the above code won't throw but it will give the wrong answer.

Why are you doing it this way? Why not just compare two DateTimes?


Yes, this code will bomb after the machine has been running for 2^31 milliseconds. You cannot selectively suppress overflow checking in VB.NET. There's only one fix for this: Project + Properties, Compile tab, scroll down, Advanced Compile Options, check "Remove integer overflow checks". It is not a terrible loss but you do lose a level of protection.

Another way to do this that doesn't cause overflow is by using DateTime.UtcNow. Subtracting produces a TimeSpan, use its TotalMilliseconds property. The accuracy is the same. Beware that it returns a Double, avoid equality checks.


In C# we just use "unchecked" block. Not sure what's the equivalent in VB.NET.


That's how I fixed the problem:

            currentTime = BitConverter.ToUInt32(BitConverter.GetBytes(Environment.TickCount), 0) #'' This code can fail with 1 tick error when changing the sign of one item.
            lastInputTime = BitConverter.ToUInt32(BitConverter.GetBytes(lastInput.time), 0)

            If currentTime - lastInputTime > m_idleTime Then

This code works because you get the bytes of the Integer and just use them as if they where an UInteger, this does not throw OverflowException.

The only problem I've seen is that you have a 1 unit error when doing the subtraction when the sign of one item has changed, not sure about what is happening but anyway having 1 tick error is not an issue.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜