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