与零值双奇怪的if语句行为语句、奇怪、行为、零值双

2023-09-04 13:07:18 作者:华衣

谁会在意向我解释如何 this.oBalance.QouteBalance 的价值被评估为真为小于零,当它显然不是?请参见下图。

Would anyone care to explain to me how the value of this.oBalance.QouteBalance is evaluated to be true for being less than zero when it clearly isn't? Please see image below.

我缺少的东西根本,当谈到在C#??

Am I missing something fundamental when it comes to comparing doubles in C#??

public double QouteBalance { get; set; }

UpdateBalance_PositionOpenned()不被称为一个循环,但是被称为作为一计时器的蜱运行一个更复杂的事件驱动程序的一部分(顺序毫秒)

UpdateBalance_PositionOpenned() is not being called in a loop, but is being called as part of a more complex event driven procedure that runs on the ticks of a timer (order of milliseconds)

编辑:原谅了code,如果它的混乱,但我不能编辑它,因为这是一个运行时错误之后相当长的运行时间,所以不敢也不会能够重新创建它。异常消息是不正确的,只是提醒自己。除后的code是code我忘了这起特殊的运行前注释掉。

Pardon the code if it's messy but I couldn't edit it as this was a run-time error after quite a long run-time so was afraid wouldn't be able to recreate it. The Exception message is not correct and just a reminder for myself. The code after the exception is code I forgot to comment out before starting this particular run.

编辑2:我建立和运行的发布模式

修改3:请原谅我的无知,但它似乎我其实因为这code在多线程环境中运行被称为一个更复杂的对象方法的一部分这得到一个计时器的滴答(活动)执行。可能会问它的定时器等待,直到它的事件处理程序内的所有code已经完成,才可以再次勾选?

EDIT 3: Pardon my ignorance, but it would seem that I am in fact running in a multi-threaded environment since this code is being called as part of a more complex object method that gets executed on the ticks (Events) of a timer. Would it possible to ask the timer to wait until all code inside its event handler has finished before it can tick again?

修改4:由于这已建立是一个多线程的问题;我会尽量给更大范围内以最佳的解决办法。

EDIT 4: Since this has been established to be a multi-threading issue; I will try to give wider context to arrive at an optimized solution.

我有一个定时器对象,其执行上的每个刻度以下内容:

I have a Timer object, which executes the following on every tick:

运行后台工作,以从文件中读取数据 当后台工作完成后,从文件中读取数据,引发 事件 在事件处理程序,运行目标code调用下面的方法 (中图)和其他多种程序,包括图形用户界面的更新。 Run a background worker to read data from file When background worker finishes reading data from file, raise an Event In the event handler, run object code that calls the method below (in the image) and other multiple routines, including GUI updates.

我想,可避免使用计时器滴答事件来读取来自文件,但这种变化会打破我的code其他地方这个问题。

I suppose this problem can be avoided by using the timer Tick events to read the from file but changing this will break other parts of my code.

推荐答案

您是从多个线程访问共享变量。这也可能是其中一个线程抛出错误的竞争条件,但调试器已经引起和连接时,变量的值发生了变化。

You're accessing shared variables from multiple threads. It's probably a race condition where one thread has thrown the error but by the time the debugger has caught and attached, the variable's value has changed.

您需要看看如何实现同步逻辑,例如把周围的共享变量等。

You would need to look at implementing synchronizing logic like locking around the shared variables, etc.

修改:为了回答您的编辑:

Edit: To answer your edit:

您真的不能告诉定时器不打勾(当然你也可以,但你开始和停止甚至在调用停止,你可能仍然收到取决于如何快速的他们被分派几个事件)。这就是说,你可以看看互锁命名空间,并用它来设置和清除,并IsBusy标志。如果你打勾方法火灾,并认为你已经工作,它只是坐在了这一轮,等待未来的蜱处理工作。我不会说这是一个很好的范例,但它是一个选项。

You can't really tell the timer to not tick (well you can, but then you're starting and stopping and even after calling Stop you might still receive a few more events depending on how fast they are being dispatched). That said, you could look at Interlocked namespace and use it to set and clear and IsBusy flag. If your tick method fires and sees you're already working, it just sits out that round and waits for a future tick to handle work. I wouldn't say it's a great paradigm but it's an option.

我指定使用Interlocked类与只使用一个共享变量反对的原因归结为一个事实,你从多个线程正在访问一次。如果你不使用互锁,可以得到两个刻度检查双方的价值并获得他们可以继续他们已经翻转标志以防止其他人之前的答案。你会击中了同样的问题。

The reason I specify using the Interlocked class versus just using a shared variable against comes down to the fact you're access from multiple threads at once. If you're not using Interlocked, you could get two ticks both checking the value and getting an answer they can proceed before they've flipped the flag to keep others out. You'd hit the same problem.

同步共享数据成员访问的更传统的方法是用锁,但你很快就会碰到问题蜱事件射击速度太快了,他们就会开始备份你。

The more traditional way of synchronizing access to shared data member is with locking but you'll quickly run into problems with the tick events firing too quickly and they'll start to back up on you.

编辑2 :要回答你有关的方法,对多个线程共享变量的同步数据的问题,它实际上取决于你在做什么特别。我们有一个非常小的窗口,进入你的应用程序在做,所以我要去这个拼凑在一起,希望所有的意见,并回答它会通知你的设计选择。

Edit 2: To answer your question about an approach to synchronizing the data with shared variables on multiple threads, it really depends on what you're doing specifically. We have a very small window into what your application is doing so I'm going to piece this together from all the comments and answers in hopes it will inform your design choice.

下面是伪code。这是基于一个问题,你问这表明你并不需要做的每一个刻度工作。蜱本身并不重要,它只是需要保持进来。在此基础上premise,我们可以用一个萎靡不振的系统检查,如果你是忙碌的。

What follows is pseudo-code. This is based on a question you asked which suggests you don't need to do work on every tick. The tick itself isn't important, it just needs to keep coming in. Based on that premise, we can use a flagging system to check if you're busy.

...
Timer.Start(Handle_Tick)
...

public void Handle_Tick(...)
{
    //Check to see if we're already busy. We don't need to "pump" the work if
    //we're already processing.
    if (IsBusy)
        return;

    try
    {
        IsBusy = true;

        //Perform your work
    }
    finally
    {
        IsBusy = false;
    }
}

在这种情况下,IsBusy可以是一种挥发性布尔,它可以被用互锁命名空间的方法,它可能是一个锁定,等你选择什么,完全由你。

In this case, IsBusy could be a volatile bool, it could be accessed with Interlocked namespace methods, it could be a locking, etc. What you choose is up to you.

如果这个premise是不正确的,你其实做必须做的工作与定时器的每一个刻度,这不会为你工作。你把自己的蜱是进来的时候你忙。你需要实现一个同步的队列中,如果你想留住每一个进来打勾。如果你的频率很高,你要小心,因为你最终会溢出。

If this premise is incorrect and you do in fact have to do work with every tick of the timer, this won't work for you. You're throwing away ticks that come in when you're busy. You'd need to implement a synchronized queue if you wanted to keep hold of every tick that came in. If your frequency is high, you'll have to be careful as you'll eventually overflow.