1

次のコードがあります。

Dictionary<string, WSResponse> responseDictionary = new Dictionary<string, WSResponse>();
List<Task> taskList = new List<Task>();
foreach (string ID in IDs)
{
      string localID = ID;

      Task newTask = Task.Factory.StartNew(() =>
      {
           WSResponse response = Query.GetListFor(localID);                    
           responseDictionary.Add(localID, response);
      });
      taskList.Add(newTask);
}

Task.WaitAll(taskList.ToArray());

このコードが実行されているサーバーで、IT チームはサーバー監視ソフトウェアを使用しており、そのソフトウェアunsafe static Dictionaryが が渡されていることを報告していると言われました。私の推測では、Task 内で Dictionary を使用すると、Dictionary は安全でないポインターとして Task スレッドに渡されます。一方で、私はこれを完全に間違っているかもしれません。これについて話している信頼できる情報源を見つけようとしましたが、失敗しました。この場合、ランタイムが何をするのか説明できる人はいますか?

ところで:とにかくDictionaryを aに交換しているConcurrentDictionaryので、アラームは必要ありません。

4

1 に答える 1

1

ディクショナリはどのように参照によってタスクに渡されますか

Dictionary は参照型なので、値渡しか参照渡しかはあまり関係ありません。しかし、たまたまクロージャーはほとんどの場合、by-ref に似ています。

あなたのコードで:

Dictionary<string, WSResponse> responseDictionary = ...;

  Task newTask = Task.Factory.StartNew(() =>
  {
       WSResponse response = Query.GetListFor(localID);                    
       responseDictionary.Add(localID, response);
  });

ディクショナリは Task ラムダのスコープ外で宣言されていますが、ラムダはそれを名前で使用します。これは許可されており、変数を「閉じる」と呼ばれます。

つまり、複数のスレッドが Dictionary にアクセスできるため、ConcurrentDictionary に置き換える必要があります。ほとんどの場合、これで診断メッセージが解決されます。

于 2013-07-15T09:40:21.207 に答える