【问题标题】:C# Starting an array of threads [duplicate]C#启动线程数组[重复]
【发布时间】:2018-01-03 08:42:51
【问题描述】:

要了解如何启动多个线程调用同一个方法,我想使用以下逻辑:

  • 创建线程数组
  • 使用 lambda 表达式初始化线程
  • 启动线程。

如果我使用 Join 函数或像这样直接启动线程,则例程可以工作:

new Thread(EnterSemaphore).Start(i);

我可以从结果中看到我正在使用的例程不起作用。并非所有线程都显示出来,我什至看到索引号为 6 的线程。我想了解为什么启动这样的线程数组会失败。

class SemaphoreLock
{

    #region Fields
    // SemaphoreSlim _sem heeft de capaciteit voor 3 elementen 
    static SemaphoreSlim _sem = new SemaphoreSlim(3); // Capacity of 3

    public readonly object StartLocker = new object();

    #endregion

    #region Constructor
    // 
    public SemaphoreLock()
    {
        Thread[] testStart = new Thread[10];

        for (int i = 1; i <= 5; i++)
        {

            // If enabled, this works
            // new Thread(EnterSemaphore).Start(i);

            // This is not working.
            testStart[i] = new Thread(() => EnterSemaphore(i));
            lock (StartLocker) testStart[i].Start();

            // Adding a join here works, every thread is started as a single thread
            //testStart[i].Join();
        }

    }
    #endregion


    #region Methods
    static void EnterSemaphore(object id)
    {
        Console.WriteLine(id + " wants to enter");

        // Block the current thread until it can enter the Semaphore
        _sem.Wait();

        Console.WriteLine(id + " is in!");
        Thread.Sleep(1000 * (int)id);
        Console.WriteLine(id + " is leaving");
        _sem.Release();

        if (_sem.CurrentCount == 3)
        {

            Console.WriteLine("Done...");
        }
    }

       #endregion

}

【问题讨论】:

  • 人们认为这不是开始,而是结束。我们必须假设,因为您没有提供minimal reproducible example。但是您发布的代码很可能是在一个简单的控制台程序中找到的,该程序调用构造函数然后退出。控制台窗口消失了,然后你就看不到你的线程在做什么了。如果您认为这不是答案,请发布一个新问题,但这次请提供所有详细信息。

标签: c# arrays thread-safety


【解决方案1】:

您的代码运行良好。使用线程Join,您只能看到不同的线程,因为Thread.Join

阻塞调用线程,直到 this 表示的线程 实例终止,同时继续执行标准 COM 和 SendMessage 抽。

作为另一个示例,您还可以使用 Thread.Sleep() 来查看类似行为:

        testStart[i] = new Thread(() => EnterSemaphore(i));
        lock (StartLocker) testStart[i].Start();
        Thread.Sleep(100);

更好的是,为了见证行为,在 for 循环的末尾使用 ReadLine()

 for (int i = 1; i <= 5; i++)
 {      
   testStart[i] = new Thread(() => EnterSemaphore(i));
   lock (StartLocker) testStart[i].Start();
 }
 Console.ReadLine();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-01
    • 2013-09-07
    • 2014-02-03
    • 2021-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多