3

次の Parallel.ForEach ループからすぐに抜け出すにはどうすればよいですか...

Parallel.ForEach(
                    webnode.ChildNodes.OfType<XmlNode>(),
                    (node,loopState) =>
                        {
                            if(threadCommand!=null &&                   threadCommand.CurrentSubIndicator.StopSignaled)
                                loopState.Stop();

                            string title = node.Attributes["Title"].Value;
                            string url = node.Attributes["Url"].Value;
                            if (!string.IsNullOrEmpty(specificItemUrl) &&
                                (!url.Equals(specificItemUrl)))
                                return;
                            Site partialSubSite = new WSS(site, Guid.Empty, title, url, "", null, null);

                            try
                            {
                                GetSite(partialSubSite, lite, readNavigation);
                            }
                            catch (Exception ex)
                            {
                                LogERError("Failed to fully read sub-site: {0}", url, ex);
                                partialSubSite.Guid = Constants.BadItemId;
                            }


                        });

if (threadCommand!=null && threadCommand.CurrentSubIndicator.StopSignaled)条件を確認してtrueになったら、すべてのスレッドを終了して実行を停止したい 。これどうやってするの?

4

4 に答える 4

2

TPL の CancellationTokens を確認します。http://blogs.msdn.com/b/pfxteam/archive/2009/06/22/9791840.aspx Parallel.Foreach() に CancellationToken を渡すと機能します。すべてのタスクを停止したい場合は、次を使用します。

cts.キャンセル()

Task のメソッド内の場所

 cts.Token.ThrowIfCancellationRequested(); 

別のタスクがプロセスをキャンセルしたためにタスクを停止する必要があるかどうかを確認したい場合。

これは、使用方法のテストされていない例です。

CancellationTokenSource cts = new CancellationTokenSource(); 
ParallelOptions options = new ParallelOptions 
                             {CancellationToken = cts.Token}; 

Parallel.ForEach(
                webnode.ChildNodes.OfType<XmlNode>(),
                 options 
                (node,loopState) =>
                    {

                        if(threadCommand!=null &&                   threadCommand.CurrentSubIndicator.StopSignaled)
                            cts.Cancel();

                        string title = node.Attributes["Title"].Value;
                        string url = node.Attributes["Url"].Value;
                        if (!string.IsNullOrEmpty(specificItemUrl) &&
                            (!url.Equals(specificItemUrl)))
                            return;
                        cts.Token.ThrowIfCancellationRequested();
                        Site partialSubSite = new WSS(site, Guid.Empty, title, url, "", null, null);

                        try
                        {
                            GetSite(partialSubSite, lite, readNavigation);
                        }
                        catch (Exception ex)
                        {
                            LogERError("Failed to fully read sub-site: {0}", url, ex);
                            partialSubSite.Guid = Constants.BadItemId;
                        }


                    });
于 2012-10-04T10:20:00.513 に答える
2

それらをすぐに停止させることはできません。キャンセルは協力的です。スレッドは、定期的にキャンセルをチェックして協力する必要があります。この場合は当てはまらないものでワーカースレッドを強制終了するだけなので、他に方法はありません。

于 2012-10-04T10:11:52.650 に答える
0

このように使用できますか

 Parallel.ForEach(
                    webnode.ChildNodes.OfType<XmlNode>(),
                   (node, loopState) =>
                    {
                        if (threadCommand != null && threadCommand.CurrentSubIndicator.StopSignaled)
                            loopState.Stop();

                        string title = node.Attributes["Title"].Value;
                        string url = node.Attributes["Url"].Value;
                        if (!string.IsNullOrEmpty(specificItemUrl) &&
                            (!url.Equals(specificItemUrl)))
                            return;


                        if (loopState.IsStopped)
                            loopState.Break();

                        Site partialSubSite = new WSS(site, Guid.Empty, title, url, "", null, null);

                        try
                        {
                            if (loopState.IsStopped)
                                loopState.Break();

                            GetSite(partialSubSite, lite, readNavigation);
                        }
                        catch (Exception ex)
                        {
                            LogERError("Failed to fully read sub-site: {0}", url, ex);
                            partialSubSite.Guid = Constants.BadItemId;
                        }

                        if (partialSubSite.Web.IsBucketWeb)
                        {
                            lock (others)
                                others.AddRange(partialSubSite.Web.SubWebUrls.Cast<string>());
                            return;
                        }
                        lock (subSites)
                            subSites.Add(partialSubSite as WSS);
                    });
于 2012-10-04T11:33:23.693 に答える
0

ParallelLoopState.Stop()この記事を見つけました。との使用の違いについて説明していParallelLoopState.Break()ます。スレッドは引き続き機能する可能性がありますが、チェックを実行して、ParallelLoopState.IsStoppedそれが真の場合は、スレッドが作業を保存していないことを確認してください。

http://msdn.microsoft.com/en-us/library/dd460721.aspx

于 2012-10-04T10:10:51.053 に答える