C#スレッディングで奇妙な問題が発生しました。C#の奇妙なスレッディング
これはスレッドを使用してagentListの各エージェントでPrint()関数を「アクティブにする」サンプルプログラムです。
class Program {
static void Main(string[] args) {
List<Agent> agentList = new List<Agent>();
agentList.Add(new Agent("lion"));
agentList.Add(new Agent("cat"));
agentList.Add(new Agent("dog"));
agentList.Add(new Agent("bird"));
foreach (var agent in agentList) {
new Thread(() => agent.Print()).Start();
}
Console.ReadLine();
}
}
class Agent {
public string Name { get; set; }
public Agent(string name) {
this.Name = name;
}
public void Print() {
Console.WriteLine("Agent {0} is called", this.Name);
}
}
そして、ここでは、私は上記のプログラムを実行するときの結果である:
Agent cat is called
Agent dog is called
Agent bird is called
Agent bird is called
しかし、私は期待を何かが最も驚くべきものがあることである
Agent lion is called
Agent cat is called
Agent dog is called
Agent bird is called
のようにすべての4つの物質が含まれています私がforeachの外にスレッドを呼び出すと、動作します!
class Program {
static void Main(string[] args) {
List<Agent> agentList = new List<Agent>();
agentList.Add(new Agent("leecom"));
agentList.Add(new Agent("huanlv"));
agentList.Add(new Agent("peter"));
agentList.Add(new Agent("steve"));
new Thread(() => agentList[0].Print()).Start();
new Thread(() => agentList[1].Print()).Start();
new Thread(() => agentList[2].Print()).Start();
new Thread(() => agentList[3].Print()).Start();
Console.ReadLine();
}
}
上記のコードの結果は、まさに私が期待したものです。だからここで何が問題なの?
あなたはループ変数の上に閉じたときに何が起こるかです::
私はBackgroundWorkerオブジェクトが好きhttp://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing -over-the-loop-variable-considered-harmful.aspx – dlev@dlev、あなたは答えを投稿して、解決済みとマークすることができます。あなたの答えは正しいです。 –
あなたが知っているのは、.Net 4.0を使用している場合は、各ループにParallelを使用して、自分が望むことをすることができます。私はそれがより適切だと思います。 – jlafay