0

許してください。でも、コードのどこで問題が発生しているのかよくわかりません。マルチスレッドのtcpサーバーの作成に取り組んでおり、辞書を使用して文字列を保存しようとしています。コードは次のようになります。

class Echo : Iprotocol
{
    public Dictionary<string, string> dictionary = new Dictionary<string, string>();
    private const int BUFFSIZE = 32; //buffer size

    private Socket client_sock; //Socket
    private Ilogger logger; // logger

    public Echo(Socket sock, Ilogger log)
    {
        this.client_sock = sock;
        this.logger = log;
    }
    public string handlewhois(string inname)
    {
        ArrayList entry = new ArrayList();
        string name = inname;
        string message = null;
        if (dictionary.ContainsKey(name) == true)
        {
            entry.Add(System.DateTime.Now + "Dictionary reference found at thread: " + Thread.CurrentThread.GetHashCode());
            message = dictionary[name];
        }
        else
        {
            entry.Add(System.DateTime.Now + "Dictionary reference not found at thread:  " + Thread.CurrentThread.GetHashCode());
            message = "ERROR: no entries found";
        }
        logger.writeEntry(entry);
        return message;
    }
    public string handlewhois(string inname, string inlocation)
    {
        ArrayList entry = new ArrayList();
        string name = inname;
        string location = inlocation;
        string message = null;
        entry.Add(System.DateTime.Now + "Dictionary reference created or updated at thread: " + Thread.CurrentThread.GetHashCode());
        dictionary.Add(name, location);
        message = "OK";
        logger.writeEntry(entry);
        return message;
    }
}

完全に正常に動作しますが、デバッグでステップスルーすると、辞書エントリが作成されているのがわかります。ただし、次の行に到達すると、logger.writeEntry(entry);

辞書に値が含まれていないため、突然消えます。

マルチスレッドと関係があるのではないかと思いますが、正直なところわかりません!

4

1 に答える 1

2

Dictionary はスレッド セーフではありません。代わりにConcurrentDictionaryの使用を検討してください。

辞書のドキュメントから:

コレクションが変更されない限り、ディクショナリは複数のリーダーを同時にサポートできます。それでも、コレクションの列挙は本質的にスレッドセーフな手順ではありません。列挙が書き込みアクセスと競合するまれなケースでは、列挙全体の間、コレクションをロックする必要があります。読み取りおよび書き込みのために複数のスレッドがコレクションにアクセスできるようにするには、独自の同期を実装する必要があります。

スレッドセーフな代替手段については、ConcurrentDictionary を参照してください。

この型の public static (Visual Basic では共有) メンバーは、スレッド セーフです。

詳細については、この SO の質問と回答を参照してください。

于 2013-03-27T10:38:47.913 に答える