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)一旦我检查条件并发现为真,我想退出所有线程以停止执行 。我怎样才能做到这一点?

4

4 回答 4

2

检查 TPL 的 CancellationTokens。http://blogs.msdn.com/b/pfxteam/archive/2009/06/22/9791840.aspx 将 CancellationToken 传递给 Parallel.Foreach() 可以使其工作。当您想停止所有任务时,只需使用:

cts.Cancel()

在你的任务方法的地方

 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 回答