簡體   English   中英

如果語句的計算結果為false,但仍然分支,就好像它是真的一樣

[英]If statement evaluates to false but still branches as if it was true

我很難過。 在異步方法中,我有一些初始保護語句,如果滿足特定條件則拋出異常。

其中之一是以下內容:

var txPagesCount = _transactionPages.Count;
if (txPagesCount == 0)
    throw new InvalidOperationException(string.Format("Cannot commit transaction {0}. It is empty.", _txId));

這應該確保_transactionPages字典中有頁面,如果沒有則拋出。

這是我運行時發生的事情(發布和調試版本,附加調試器):

頁數為3

所以字典中的頁數是3。

if語句的計算結果為false

因此,正如預期的那樣,將3比0的if語句評估為false。

但是,當進一步邁進時:

進入分支的步驟

它進入分支,好像if語句計算為true,並拋出異常。

我在這里錯過了什么?

UPDATE

當我這樣做:

private static readonly object _globalLock = new object();

public async Task<Checkpoint> CommitAsync(PageNumber dataRoot, PageNumber firstUnusedPage)
{
    lock (_globalLock)
    {
        if (IsCompleted)
            throw new InvalidOperationException(string.Format("Cannot commit completed transaction {0}", _txId));
        var txPagesCount = _transactionPages.Count;
        if (txPagesCount == 0)
            throw new InvalidOperationException(string.Format("Cannot commit transaction {0}. It is empty.", _txId));
    }

if語句不分支以拋出異常。 調試和發布版本都是這種情況。 是什么搞砸了調用堆棧? 另外,如果不是鎖,我添加System.Threading.Thread.MemoryBarrier(); if語句之后,它不會進入分支。

更新2

這個謎團變得更大了。 這幾乎就像使用了c ++范圍規則:D下面的代碼( 在調試版本中 )將顯示預期的行為:不進入分支而不拋出。 發布版本中 ,它將進入分支並像以前一樣拋出。

private static readonly object _globalLock = new object();

public async Task<Checkpoint> CommitAsync(PageNumber dataRoot, PageNumber firstUnusedPage)
{
    //lock (_globalLock)
    {
        if (IsCompleted)
            throw new InvalidOperationException(string.Format("Cannot commit completed transaction {0}", _txId));
        var txPagesCount = _transactionPages.Count;
        if (txPagesCount == 0)
            throw new InvalidOperationException(string.Format("Cannot commit transaction {0}. It is empty.", _txId));
    }

如果我注釋掉“范圍括號”,它將進入分支並拋出異常(如我原始圖像中所示)。

最后? UPDATE

那很糟糕。 我對不相關的代碼區域做了一些更改,現在我不再能夠重現問題了。

哇,異步調試。

我只有一種方法可以有效地做到這一點。 使用跟蹤(希望是正確的東西,也許是log4net)。 確保在每一行輸出時間戳和threadId。 (還支持在需要時每次調用跟蹤庫的輸出同步,而不必一直打開)

真的是這樣的。

注意:只需寫入文件或標准輸出就可以獲得第一個紅色,但如果您開始使用它,請獲取一個庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM