C# } For 循环问题

C# } For Loop Issues

你好,我的学校有我需要访问的记录,但我忘记了我的用户 ID,所以我制作了一个程序,可以下载任何可能的 PDF 并在其中搜索我的名字。如果它找到我的,它会提醒我,但是当程序关闭并说 "We found a file containing Sean File Name is : xxxxxx.pdf" 实际数字部分将关闭,无论 for 循环增加了多少,即使这是在一个单独的方法上!顺便说一句,学校名称将被加星标!

*顺路!在 Search() 中,我使用 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);
      }
    }
  }
}

您 运行 进入的内容称为 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#?