2016-07-15 113 views
0

我有一個奇怪的行爲,在我的一個ASP.net Web服務的基本方法之一。首先:這是自多年以來一直有生產力的代碼,迄今爲止還沒有報道過任何問題。但在我的單元測試中,我認識到這個問題有兩次,所以現在我很困惑,如果它只是在我的開發中,或者它是一個真正的問題。「ArgumentException:項目已被添加」哈希表

這裏是我的代碼片段,其中的錯誤

System.ArgumentException:項目已添加。鍵在字典: '6' 鍵被加入: '6'

發生時_messages.Add叫做:

public Message Add(GatewayMessageTypes type, string strMessage, CultureInfo language) 
{ 
    var message = new Message(type, strMessage, language); 

    int intCount = _messages.Count + 1; 
    if (_messages.ContainsKey(intCount)) 
    { 
     _messages.Remove(intCount); 
    } 

    _messages.Add(intCount, message); 

    return message; 
} 

_messages定義爲:

public class MessageHandler 
{ 
    private readonly Hashtable _messages = new Hashtable(); 

而這種的MessageHandler用於在我所有定義在基類中的Web服務中

public abstract class ServiceBase 
{ 
    public MessageHandler MessageHandler { get; protected set; } 

這是堆棧跟蹤:

at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add) 
    at System.Collections.Hashtable.Add(Object key, Object value) 
    at GISGatewayCore.MessageHandler.Add(GatewayMessageTypes strType, String strMessage, CultureInfo language) in GISGateway\GISGatewayCore\MessageHandler.cs:line 69 
    at GISGatewayCore.MessageHandler.AddAndLog(GatewayMessageTypes type, String strMessage, CultureInfo language) in GISGateway\GISGatewayCore\MessageHandler.cs:line 81 
    at GISGateway.Services.GetClosestFacilityServices.<>c__DisplayClass4.<GetClosestFacilities>b__1(Object index) in GISGateway\GISGateway.Services\GetClosestFacilityServices.cs:line 592 
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart(Object obj) 

這是正確的,目前已經在收集6項和6號長相酷似應添加新的消息。 那麼問題是什麼?

  1. 刪除失敗?它執行速度慢嗎?但代碼是同步的,不應該有任何問題?
  2. 兩個具有相同值的不同條目?我相當肯定這可以排除
  3. 是否有兩個並行進程使用相同的代碼?我的單元測試共同使用這個部分,我的兩個測試使用相同的Web服務端點。但是我的任何對象都不是靜態的,那麼這怎麼會發生呢?
+0

您還必須顯示消息類別。 – user3185569

+0

@ user3185569你爲什麼認爲它對這個問題負責?這是一個簡單的類,只有屬性,裏面沒有邏輯。 – Max

回答

1

我明白你的意思,應該同步運行。然而,試試這個,看看它的工作原理:

public Message Add(GatewayMessageTypes type, string strMessage, CultureInfo language) 
{ 
    lock(_messages) 
    { 
    var message = new Message(type, strMessage, language); 

    int intCount = _messages.Count + 1; 
    if (_messages.ContainsKey(intCount)) 
    { 
     _messages.Remove(intCount); 
    } 

    _messages.Add(intCount, message); 

    return message; 
    } 
} 

我可能是從同一個「會議」兩個來源叫,像一個控制器上的ajax調用。

+0

這是個好主意,我會給它一個機會。 但是:我不應該更好地使用單獨的鎖對象而不是要修改的對象嗎? – Max

+0

我想是的,但使用相同的對象簡化了它的使用,並確保你不使用錯誤的:) –