2016-07-22 134 views
-1

你好,所以我的学校有,我需要访问的记录,但我忘记了自己的用户ID,所以我做了一个程序,它会下载任何可能的PDF和搜索他们为我的名字。如果发现我的,它会提醒我,但是当程序关闭时,并且说:“我们发现一个包含Sean文件名的文件是:xxxxxx.pdf”实际的数字部分将会关闭,尽管for循环增加了很多是在一个单独的方法! BTW学校名称将出演!C#} For循环问题

*顺便说一句!在搜索()我用I-10作为一个临时的解决办法,但我想他们一定是一个更好的办法*


using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Net; 
using BitMiracle.Docotic.Pdf; // pdf parser/viewer 
using System.IO; 
using System.Threading; 

namespace XXXXXXX_TEMP 
{ 
    class Program 
{ 
    static void Main(string[] args) 
    { 
     Program p1 = new Program(); 
     p1.Start(); 
    } 

    private void Start() 
    { 
     WebClient wc = new WebClient(); 
     for (int i = 200000; i < 999999999; i = i + 10) 
     { 
      try 
      { 
       wc.DownloadFile("XXXXXXXXXXXXXXXXXXXXXX/" + i + ".pdf", i + ".pdf"); 
      } 
      catch (WebException) { 
       continue; 
      } 
      PdfDocument pdf = new PdfDocument(i + ".pdf"); 
      Thread a = new Thread(() => Search(i, pdf)); 
      a.Start(); 

      if (i == 999999) { 
       Console.ReadLine(); 
      } 
     } 
    } 

    private void Search(int i, PdfDocument pdf) 
    { 
     i = i - 10; 
     String html = pdf.GetText(); 
     if (html.ToLower().Contains("sean")) 
     { 
      Console.WriteLine("Found File Containing Sean! File Name Is : " + i + ".pdf\n"); 
      Console.WriteLine("PDF Text = " + html); 
     } 
    } 
    } 
} 
+0

这个非常常见的错误已经在一些其他堆栈溢出问题已经解决,包括标记的重复。请特别参考[这个答案](http://stackoverflow.com/a/3157918)以获得很好的解释。 –

+0

@PeterDuniho很抱歉,这种情况经常发生在我身上,因为我有问题的话。下次抱歉时我会小心得多。 –

回答

0

你所碰到的被称为closing over the loop variable。你应该仔细研究链接的答案以及它链接到的博客条目。

的立即解决你的问题是的i拷贝传递给线程。那就是:

int index = i; 
Thread a = new Thread(() => Search(index, pdf)); 

然而,你可能会发现,启动所有这些线程严重停滞不前您的系统,并让所有的线程挂可能吃了资源,导致内存溢出异常。一个清洁的方式做到这一点是调用ThreadPool.QueueUserWorkItem,像这样:

ThreadPool.QueueUserWorkItem(o => Search(index, pdf)); 

或者,在.NET的新版本:

Task.Run(() => Search(index, pdf)); 

更多信息请参见Simplest way to do a fire and forget method in C#?关于发射后不管线程。

+0

@SeandaPotato:主要问题是您的解决方案*不正确*,因为它可以跳过一些文档并多次处理其他文档。任何速度差异将在微秒左右。 'i-10'的东西不可靠。 –

+0

啊好的。还有一个问题,所以我从MSDN中了解到的是,Task.Run()是Task.Facotry.StartNew()的新而简单的方法,但它确实限制了用户无法做某些事情。有人认为Task.Run令我感到困惑的是,它说它运行你将它从线程池中发送出去。我是否需要制作该线程池,还是已经存在。还有ThreadPool.QueueUserWorkItem(o => Search(index,pdf));我需要在这里创建一个线程池,还是再由系统处理? –

+0

@SeandaPotato:线程池由系统自动创建和管理。有关更多信息,请参阅https://msdn.microsoft.com/en-us/library/0ka9477y(v=vs.110).aspx。 –