C# 使用循环中的线程

C# 使用循环中的线程,c#,multithreading,C#,Multithreading,我有一个循环,如下所示 while (something) { System.Threading.Thread newthread = new System.Threading.Thread(() => CreatePDF(strPDFHTML, filePath)); newthread.Start(); Console.WriteLine("Creating PDF."); } 当我创建一个新的Thread对象并像在循环中一样将其放置在newthrea

我有一个循环,如下所示

while (something)
{
     System.Threading.Thread newthread = new System.Threading.Thread(() => CreatePDF(strPDFHTML, filePath));
     newthread.Start();

     Console.WriteLine("Creating PDF.");
}

当我创建一个新的
Thread
对象并像在循环中一样将其放置在
newthread
中时。。。在循环的第二次迭代中,上一个运行的线程是否被覆盖/中断?会出现什么问题(如果有)?

线程的句柄丢失,但线程本身将继续运行,直到完成。除非您有一些内部通信,否则您将无法确定线程何时完成

[…]上一个正在运行的线程是否被覆盖

实际上它并没有被覆盖:您正在每个迭代中创建一个新的引用

这应该没有问题,除非您想在整个循环中管理正在创建的线程(例如,如何结束某个线程?)

另一方面,当(某物)一直在创建线程时,我想第二个线程会有问题,因为该文件可能是从其他线程使用的。使用任务工厂和等待当你需要等待所有我会更新答案,你怎么能与任务



您可以执行Task.WaitAll()或,如果需要取消,您可以添加取消令牌;您还可以在主线程中获得AggreateException,这将帮助您找到问题所在et.c

如果我们以逻辑方式浏览您的程序,我们可以准确地了解到底发生了什么

  • 在内存中创建一个位置来存储
    线程
    对象,我们将其称为
    newThread

    System.Threading.Thread newthread
    
  • 创建
    Thread
    对象的新实例,并在
    newThread
    变量中放置对该对象的引用

    newthread = new System.Threading.Thread(() => CreatePDF(strPDFHTML, filePath));
    
  • 您可以查看
    newThread
    中的指针,然后跟随它找到
    Thread
    对象,然后在该线程上调用
    Start()
    方法

    newthread.Start();
    
  • 循环结束,我们释放了变量
    newThread
    ,但是
    newThread
    只是一个指向真实对象的指针,因此线程继续在后台运行,然后我们重复这个过程

    }
    
  • 在本例中,您甚至不需要创建内存句柄
    newThread
    。您正在存储指针,以便以后再次使用。当您创建要开始的对象时,您还有一个指向该对象的指针,因此您可以在开始时调用该对象上的start,而不用费心保存对线程的引用

    new System.Threading.Thread(() => CreatePDF(strPDFHTML, filePath)).Start();
    

    上面我只是创建了Thread对象并对其调用start。它的功能与您的代码完全相同。然而,无论如何,它都不会费事使线程句柄立即丢失。

    不,也许会。取决于
    CreatePDF
    正在做什么,以及您一次启动了多少线程。“覆盖线程”对您来说意味着什么?CreatePDF大约需要一秒或2…通过覆盖一个线程,我的意思是之前的线程在这段时间内停止并被新线程替换thread@Suresh好的,我明白了。您可能应该熟悉C#中引用类型和变量的工作方式。覆盖引用不会以任何方式影响被引用对象。。。。?这完全没有错。这取决于CreatePDF如何写入文件系统。如果它写入内存流呢?或者,如果它有线程同步(即监视器、readerwriterlockslim…),所以不能一次写入一个文件呢!!CreatePDF写入文件时两者都是错误的。写入内存时会出现访问问题。稍后会出现内存异常。你不知道这段时间(某物)还活着;这是一个代码气味。NET提供了许多新技术来解决这些问题,例如创建PDF不会有任何问题,因为每个CreatePDF调用都会使用不同的名称保存PDF。我的代码现在运行得非常好。我担心当数据量很大时它会如何工作…@BassamAlugili争辩道:我相信你的答案绝对错误,它没有回答OP的问题…感谢Ben,它已经很好地解释了
    ,例如,你将如何中止一个线程?
    你不会,因为中止线程纯粹是邪恶的,你不应该尝试这样做。@Servy我知道,但你知道我想在我的回答中传达什么:你想控制你正在启动的线程。邪恶与否,一旦一个线程启动,你将无法取消它。当我说“abort”时,我并不是说
    Thread.abort
    。保持冷静!!那评论有一半是开玩笑的。虽然您不应该中止线程,而且我确实认为这是一个糟糕的示例,但您试图表达的观点是明确的,而且是不相关的。别发疯了。@Servy我在一些问题和/或答案中收到了您的一些评论,我觉得您并不总是试图为我的贡献增值。当我在收件箱中看到“Servy”时,我知道这将是一条“确定的、无可辩驳的信息”。这就是一个奇怪的词如何破坏一个答案(从你的角度看)。无论如何,我已经将“中止”替换为“设法结束”。也许我完全错了,现在我的答案中的抽象信息已经改变了很多(讽刺!)。
    new System.Threading.Thread(() => CreatePDF(strPDFHTML, filePath)).Start();