List.AsParallel() - 如何命名我的线程?

发布于 2024-10-20 16:18:07 字数 312 浏览 0 评论 0原文

我习惯

List.AsParallel().WithDegreeOfParallelism(3).ForAll(x => Worker(x));

将 Worker 应用于列表的每个元素。

如何命名 Worker 运行的线程,以便当每个 Worker(x) 线程终止时 VS 调试器告诉我: Thread <>;终止,以便我可以区分线程?

我需要这个,因为程序在一段时间后停止执行列表中的元素,并且线程刚刚终止。

I use

List.AsParallel().WithDegreeOfParallelism(3).ForAll(x => Worker(x));

to apply Worker on each element of the list.

How can I name the threads on which Worker runs, so that when each Worker(x) thread is terminated the VS debugger tells me: Thread <<for elem abcde>> terminated, so that I can differentiate between threads?

I need this because the program just stops executing elements in the list after some time, and the threads just terminate.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

醉生梦死 2024-10-27 16:18:07

我正在使用 Thread.CurrentThread.ManagedThreadId 来查看哪个线程正在被重用。
这个想法在下面的测试中得到了体现:

[Test]
public void ThreadNamesTest()
{
    var rnd = new Random();
    var range = Enumerable.Range(0, 50);

    var rangeBack = new Dictionary<int, int>();
    var rangeBackLocker = new object();

    range.AsParallel().AsOrdered()
        .WithDegreeOfParallelism(4).ForAll(x =>
    {
        lock (rangeBackLocker)
        {
            rangeBack.Add(x, Thread.CurrentThread.ManagedThreadId);
        }
        Thread.Sleep(100 * rnd.Next(10));         
    });

    Assert.AreEqual(rangeBack.GroupBy(x=>x.Value).Count(), 4);
}

I'm using Thread.CurrentThread.ManagedThreadId to see which thread is being reused.
The idea is shown in the test below:

[Test]
public void ThreadNamesTest()
{
    var rnd = new Random();
    var range = Enumerable.Range(0, 50);

    var rangeBack = new Dictionary<int, int>();
    var rangeBackLocker = new object();

    range.AsParallel().AsOrdered()
        .WithDegreeOfParallelism(4).ForAll(x =>
    {
        lock (rangeBackLocker)
        {
            rangeBack.Add(x, Thread.CurrentThread.ManagedThreadId);
        }
        Thread.Sleep(100 * rnd.Next(10));         
    });

    Assert.AreEqual(rangeBack.GroupBy(x=>x.Value).Count(), 4);
}
開玄 2024-10-27 16:18:07

您可以在您的 Worker 方法中设置线程名称:

Thread.CurrentThread.Name = "PLinq Thread: " + x

但是线程将被重用(并且在您的工作完成时不一定会终止,如果它们被放回池中),所以您不会'您不会看到集合中的每个项目都被终止 - 您可能只会在终止消息中看到每个线程的最后项目的名称。

编辑: Gilad 在评论中指出,如果尝试设置已经有名称的线程的名称,将会抛出异常。我想这使得你想要做的事情完全不可能,因为线程可以被重用。

You could probably set the thread name in your Worker method:

Thread.CurrentThread.Name = "PLinq Thread: " + x

However threads will be reused (and not necessarily terminated when your work is done, if they're put back into a pool), so you won't see them being terminated for each item in your collection - you'll just probably see the names of the last items from each thread, in the termination messages.

Edit: Gilad points out in comments, an exception will be thrown if you try to set the name of a thread that already has a name. I guess this makes what you're trying to do completely impossible, given threads can be reused.

扛起拖把扫天下 2024-10-27 16:18:07

PLinq 不会为其处理的每个元素创建一个新线程,它可以在单个线程上处理多个元素,因此我认为命名线程并不是您真正需要的。

我建议在 Worker 启动时,将当前元素和当前线程的 ID 写入调试控制台。然后,当线程终止时,您将能够检查调试输出以查看哪个是该线程上启动的最后一个元素。

PLinq doesn't create a new thread for each element that it processes, it can process multiple elements on a single thread, so I don't think naming the threads is really what you need here.

I'd suggest that at the start of Worker, you write out to the debug console the current element, and the ID of the current thread. Then when a thread is terminated, you'll be able to check your debug output to see which was the last element to be started on that thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文