私はParallel.Forループを7500を少し上回るオブジェクトで実行しています。そのforループの中で、私はこれらのオブジェクトのそれぞれに対して、特に2つのWebサービスと2つの内部メソッドを呼び出すいくつかのことをしています。 Webサービスは単にオブジェクトを検査し、処理して文字列を返します。それをオブジェクトのプロパティとして設定します。同じ2つの内部メソッドにも同じです。Parallel.For約1370反復後にフリーズする理由は分かりません
私はディスクに何も書き込んでいない、またはディスクから読み込みません。
また、winformsアプリケーションのUIをラベルと進行状況バーで更新して、どこにいるのかをユーザーに知らせることもできます。ここでは、コードです:
var task = Task.Factory.StartNew(() =>
{
Parallel.For(0, upperLimit, (i, loopState) =>
{
if (cancellationToken.IsCancellationRequested)
loopState.Stop();
lblProgressBar.Invoke(
(Action)
(() => lblProgressBar.Text = string.Format("Processing record {0} of {1}.", (progressCounter++), upperLimit)));
progByStep.Invoke(
(Action)
(() => progByStep.Value = (progressCounter - 1)));
CallSvc1(entity[i]);
Conversion1(entity[i]);
CallSvc2(entity[i]);
Conversion2(entity[i]);
});
}, cancellationToken);
これはwin7の32ビットマシン上で行われています。
なぜインクリメンタが約1370(1361、1365、1371)になったときに、突然これが凍結するかについてのアイデアはありますか?
これをどのようにデバッグして何がロックされているかを知るためのアイデアはありますか?
EDIT:
以下のコメントにいくつかの答え:
@BrokenGlass - いや、いや相互運用。 x86コンパイルを試してみましょう。
@chibacity - バックグラウンドタスクであるため、UIがフリーズしていません。フリーズするまでは、プログレスバーとラベルは約2秒ごとに表示されます。それが凍ったら、動くのを止めるだけです。私はそれが停止した番号が処理されたことを確認できますが、それ以上のことは確認できません。デュアルコア2.2GHzでのCPU使用率は、動作中はそれぞれ3〜4%、1〜2%は凍結すると最小限に抑えられます。
@Henk Holterman - 1360になるまでには10-12分かかります。はい、これらのレコードはすべて処理されたが、残りのレコードは処理されていないことが確認できます。
@CodeInChaos - ありがとう、私はそれを試してみよう!このコードは、私が並行して取り出した場合には機能しますが、それはちょうど永遠と一日かかるのです。私はスレッドの数を制限しようとはしませんでしたが、そうです。
EDIT 2:
Webサービスで何が起こっているかを基本的にWebサービス
で何が起こっているかのようないくつかの詳細は、彼らはいくつかのデータを渡すと、データ(XmlNodeの)を受け取るということです。そのノードはConversion1プロセスで使用され、次にCallSvc2メソッドなどに送信されるエンティティに別のプロパティを設定します。これは次のようになります。
private void CallSvc1(Entity entity)
{
var svc = new MyWebService();
var node = svc.CallMethod(entity.SomeProperty);
entity.FieldToUpdate1.LoadXml(node.InnerXml);
}
private void Conversion1(Entity entity)
{
// Do some xml inspection/conversion stuff
if (entity.FieldToUpdate1.SelectSingleNode("SomeNode") == "something") {
entity.FieldToUpdate2 = SomethingThatWasConverted;
}
else {
// Do some more logic
}
}
private void CallSvc2(Entity entity)
{
var svc = new SomeOtherWebService();
var xmlNode = svc.MethodToCall(entity.FieldToUpdate2.InnerXml);
entity.AnotherXmlDocument.LoadXml(xmlNode.InnerXml);
}
ご覧のとおり、わかりやすいものです。いくつかの変換方法では多くのことが起こっていますが、どれもブロックされてはいけません。また、以下に述べるように、すべてがWebサービス呼び出しに載っている「待機中」状態にある1024のスレッドがあります。私はここでhttp://www.albahari.com/threading/を読んで、MaxThreadsは32ビットマシン上の.Net 4に対して1023にデフォルト設定されていると読んでいます。
私がここにいることを考えれば、待機中のスレッドをどのように解放できますか?
前にも同様の問題がありました。それが何か変わるかどうかを確認するために、x86モードでプロジェクトを構築しようと考えていました。あなたはあなたの仕事でどんなInterOpもやらないでしょう? – BrokenGlass
凍っているのか、それとも非常に遅いのですか? CPU使用率はどのくらいですか? –
まだTPLで作業していませんが、デバッガを起動して、どのメソッドが呼び出されたのかを確認することはできません。通常のforループに置き換えるとコードは機能しますか? 'Parallel.For'を使用して1つまたは2つのスレッドに制限するとどうなりますか? – CodesInChaos