C# Parallel.ForEach仅在代码未运行时启动时执行两次?
我正在使用一个Windows服务,我试图使用Parallel.ForEach生成唯一的定时线程。问题是,如果我在VS中将代码单独保留几个小时,或者如果我停止服务几个小时并启动任何备份,那么初始启动代码将执行两次。下面是服务的OnStart正在调用的静态void中的一个片段C# Parallel.ForEach仅在代码未运行时启动时执行两次?,c#,multithreading,parallel-processing,task-parallel-library,C#,Multithreading,Parallel Processing,Task Parallel Library,我正在使用一个Windows服务,我试图使用Parallel.ForEach生成唯一的定时线程。问题是,如果我在VS中将代码单独保留几个小时,或者如果我停止服务几个小时并启动任何备份,那么初始启动代码将执行两次。下面是服务的OnStart正在调用的静态void中的一个片段 Parallel.ForEach(urls, url => { PageGrabber pagegrab = new PageGra
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—非常无聊 我认为问题在于您已通过pageGrabber订阅了已用事件。已用+=。。。 该事件是否引发是可能的。 因此,在某些情况下,如果引发事件,您的方法将被调用两次,否则将被调用一次
我不认为您可以通过使用task array而不是parallel.Foreach更改并行实现来解决这个问题。这可能会导致问题发生的频率降低,这在并行编程中是一个非常糟糕的症状。你不应该让问题变得更加困难,从而使其逐渐消失!你应该完全移除它们 所以梅兰德夫走上了正确的道路。创建使用System.Timers.Timer的类实例时,它会立即触发已用事件,因为Interval属性设置不正确。因此:
pagegrab.Elapsed += (obj, e) =>
{
pagegrab.CheckXML();
};
pagegrab.CheckXML();
由于正确设置了间隔的类的实例已不在内存中,导致在一段时间内未发生任何事件时重复执行。我的愚蠢-现在都解决了。感谢所有的评论和建议。您发布的代码中哪一部分是“初始启动代码”?或者是在其他地方?唯一缺少的部分是它读取包含url的文本文件并用它们创建url对象的部分。它在一个试捕区。获取URL,创建一个URL对象,将其添加到URL类型的列表中,然后是foreach循环-就是这样。这真的很基本,这就是我为什么要这样做的原因。调试也相当困难,因为只有在6个小时内没有任何操作的情况下才会发生重复执行是对来自多个几乎同时发生的线程的请求的响应吗?或者它是在一个受控环境中响应单个请求而发生的?i、 e.您确定没有调用封闭方法2x吗?我在发布的代码中没有看到任何会导致您出现问题的内容。例如,我可以打开VS2010并加载解决方案。在项目上单击鼠标右键,然后选择“调试”,则会发生复制。无论我打开/关闭多少次,再次调试项目,直到我离开电脑大约6-8个小时后才会发生。当作为编译后的服务运行时,情况也是如此,但根本不一致。我已经在调试器中逐步检查了代码,并添加了一些额外的日志语句,唯一重复的代码是在ForEach循环中调用的代码-非常奇怪。您应该发布一个最小的完整程序,以暴露您的问题。对一个部分可用的代码进行推理是徒劳的。我并不反对——那么有没有关于设置已用事件的替代方案的建议呢?在这种情况下-对象中的System.Timers.Timer需要在其自己的时间间隔上运行。@kpcrash我不知道您的PageGrabber类,以及所经过事件的责任。