在parallel.ForEach循环中获取一个线程id

ved*_*eda 6 c# multithreading parallel.foreach

有没有办法在Parallel.FoEach循环中找到线程ID.我尝试过使用var threadId = Thread.CurrentThread.ManagedThreadId - 1;,但它没有给我正确的索引.

这是一个简单的例子:

private void TestProgram()
    {
        int numThreads = 1;

        var values = new List<float>();
        for (int i = 0; i < numThreads; ++i)
        {
            values.Add(i);
        }

        var data = new List<int>();
        for (int i = 0; i < numThreads; ++i)
        {
            data.Add(i);
        }


        Parallel.ForEach(data, new ParallelOptions{MaxDegreeOfParallelism = numThreads}, i =>
            //foreach (var i in data)
        {
            var threadId = Thread.CurrentThread.ManagedThreadId - 1; // make the index to start from 0

            values[threadId] += i;
        });
    }
Run Code Online (Sandbox Code Playgroud)

即使在设置之后MaxDegreeOfParallelism to 1,我仍然得到threadId大于1.

有没有办法在上面的场景中找到Parallel.ForEach中的线程ID?

注意:我可以在我使用的示例中使用Parallel.For.但我的问题是在Parallel.ForEach中找到它

Xir*_*ema 5

ThreadID由底层环境分配,并且不保证从0到[线程数]或甚至从运行到运行一致.

关于threadID只有几个合同,甚至不保证这些合同:

  • 你不会得到一个ThreadID 0
  • ThreadID 1通常是为主线程保留的


use*_*902 5

由于Parallel.ForEach是任务库的一部分,因此Task.CurrentId可以让您更接近您所寻找的内容:

   var data = new[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };


   Parallel.ForEach(data, new ParallelOptions { MaxDegreeOfParallelism = 4 }, i =>
   {
            Console.WriteLine(Task.CurrentId);
   });
Run Code Online (Sandbox Code Playgroud)

输出为1 1 1 1 1 1 1 1 1 1 2 2 1

但是,文档中有一个免责声明:

任务ID按需分配,并不一定代表创建任务实例的顺序.请注意,虽然冲突非常罕见,但不保证任务标识符是唯一的.