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#?。
你好,我的学校有我需要访问的记录,但我忘记了我的用户 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#?。