1

Parallel.ForEachを使用して一意のタイミングスレッドを生成しようとしているWindowsサービスに取り組んでいます。問題は、VSでコードを数時間そのままにしておくか、サービスを数時間停止してバックアップを開始すると、最初の起動コードが2回実行されることです。これは、サービスのOnStartが呼び出している静的なvoidからのスニペットです。

Parallel.ForEach(urls, url =>
                    {
                        PageGrabber pagegrab = new PageGrabber(url);
                        if (url.Type.ToLower() == "http")
                        {
                            pagegrab.Elapsed += (obj, e) =>
                                {
                                    pagegrab.CheckNormal();
                                };
                            pagegrab.CheckNormal();
                        }
                        else
                        {
                            pagegrab.Elapsed += (obj, e) =>
                            {
                                pagegrab.CheckXML();
                            };
                            pagegrab.CheckXML();
                        }
                    }
                    );

これは、スレッドを直接使用する場合はうまく機能しますが、このコードを少し更新したかったのです。重複実行はすぐに発生します。PageGrabberオブジェクトは、WebClientを使用してHTMLまたはXMLを文字列としてダウンロードするだけであるという点で、非常に単純です。これは非常に退屈です。

4

2 に答える 2

3

問題は、そのイベントが発生する可能性があるかどうかElapsedによってイベントにサブスクライブしたことだと思います。pageGrabber.Elapsed +=...そのため、イベントが発生した場合、メソッドは 2 回呼び出される場合もあれば、1 回呼び出される場合もあります。

並列実装を変更する (の代わりにタスク配列を使用する) ことによって、この問題を解決できるとは思いませんParallel.Foreach。問題が発生する頻度が減る可能性がありますが、これは並列プログラミングでは非常に悪い症状です。問題が発生する前提条件を難しくすることで、問題が薄れていくのを許してはなりません。それらを完全に削除する必要があります。

于 2012-12-05T18:31:11.283 に答える
0

したがって、mehrandvdは正しい道を進んでいました。System.Timers.Timerを使用するクラスのインスタンスを作成すると、Intervalプロパティが正しく設定されていなかったため、すぐにElapsedイベントが発生していました。したがって:

pagegrab.Elapsed += (obj, e) =>
                        {
                            pagegrab.CheckXML();
                        };
                        pagegrab.CheckXML();

Intervalが正しく設定されたクラスのインスタンスがメモリに存在しなくなったため、しばらくの間何も起こらなかったときに重複実行が発生しました。私の愚かさ-すべてが今修正されました。すべてのコメントと提案をありがとう。

于 2012-12-29T16:44:07.753 に答える