c#多线程——线程不运行

本文关键字:运行 线程 多线程 | 更新日期: 2023-09-27 18:03:05

我正在从平常的c++编程中自学c#,现在我正在做线程。

下面的简单代码可以很好地编译,并且应该通过线程在循环中输出哔哔声,持续30秒。

using System;
using System.Runtime.InteropServices;
using System.Threading;
class BeepSample
{
    [DllImport("kernel32.dll", SetLastError=true)]
    static extern bool Beep(uint dwFreq, uint dwDuration);
    static void Main()
    {
        Console.WriteLine("Testing PC speaker...");
        for (uint i = 100; i <= 20000; i++)
        {
            var BeepThread = new Thread(delegate() { Beep(i, 30000); });            
        }
        Console.WriteLine("Testing complete.");
        Console.ReadLine();
    }
}

唯一的问题是线程似乎不工作。

我知道我错过了一些基本的东西。

任何想法?

c#多线程——线程不运行

您忘记启动MSDN线程link

for (uint i = 100; i <= 20000; i++)
{
    var BeepThread = new Thread(delegate() { Beep(i, 30000); });
    BeepThread.Start();
}

然而这看起来很可疑。为什么需要19900个线程?也许你想要有一个线程,里面有一个循环,暂停很短的时间,通过beeper输出不同的频率。

唯一的问题是线程似乎不工作。

这方面从部分中可以清楚地看出,您没有启动线程以使它们执行任何操作

代码有许多其他问题:

  • 关闭问题,需要进一步修改

    for (uint i = 100; i <= 20000; i++)
    {
      int icopy = i;
      var BeepThread = new Thread(delegate() { Beep(icopy, 30000); });    
      BeepThread.Start();        
    }
    
  • Thread类将启动foreground threads,每个逻辑处理器核心有能力一次处理一个线程,每个Thread对于computation and memory来说是非常昂贵的资源,因为它需要分配Thread Environment Block, Kernel Stack Memory, User Stack Memory,当前的代码即使运行,也会杀死你的系统,你大多数情况下必须杀死进程才能出来

  • Console.ReadLine();只会阻塞Main Thread / Ui Thread,即使Main thread / Ui thread退出并且没有阻塞,其他处于前台的线程也会继续,理想的阻塞方法是在每个线程对象上调用Join,这将要求主线程等待直到完成

  • 重写相同代码的首选方法之一是使用任务并行库:

     Parallel.For(100, 20000,
     , new ParallelOptions { MaxDegreeOfParallelism =  
    Environment.ProcessorCount } 
    i =>
    {
       int icopy = i;
        Beep(icopy, 30000);
    });
    

好处:

  • 代码不会创建那么多线程并杀死系统
  • thread pool (Background threads)上工作,只使用所需的线程数被调用,最大数量永远不会超过系统的Processor count,并且会少得多,因为线程被重用,因为没有主要的长时间运行的计算
  • 自动阻塞Main thread / Ui Thread

好的,谢谢大家。我去吃午饭了。

我实现……

for (uint i = 500; i <= 550; i++)
    {
        uint icopy = i;
        var BeepThread = new Thread(delegate() { Beep(icopy, 30000); });
        BeepThread.Start(); 
    }

效果很好。

正如预测的那样,线程在主线程执行后没有终止,但是它做了我想要的,这是很棒的。

保佑你们。