.net 在parallel.foreach上迭代时,我可以只取消一个线程吗?

.net 在parallel.foreach上迭代时,我可以只取消一个线程吗?,.net,multithreading,parallel-processing,parallel.foreach,.net,Multithreading,Parallel Processing,Parallel.foreach,当我使用parallel.foreach时,有没有办法取消一个特定的线程 我知道我可以使用cancelToken.token使用parallelOptions取消所有线程,但如何取消一个特定线程 我知道,如果我创建的是线程列表而不是parallel.foreach,那么选择要取消的线程是没有问题的,但我希望我的程序以并行顺序运行,而不仅仅是异步运行,因为我希望使用所有CPU,而不仅仅是分割CPU资源。我想说清楚,并行类使用队列来排队和执行工作 为了回答你的问题,我不认为有一种方法可以取消一个特定

当我使用parallel.foreach时,有没有办法取消一个特定的线程

我知道我可以使用cancelToken.token使用parallelOptions取消所有线程,但如何取消一个特定线程


我知道,如果我创建的是线程列表而不是parallel.foreach,那么选择要取消的线程是没有问题的,但我希望我的程序以并行顺序运行,而不仅仅是异步运行,因为我希望使用所有CPU,而不仅仅是分割CPU资源。

我想说清楚,并行类使用队列来排队和执行工作

为了回答你的问题,我不认为有一种方法可以取消一个特定的线程本身,但是你可以中断并行。因为不使用取消令牌


请参阅MSDN上的以下内容:如何:。

为了清楚起见,并行类使用来排队和执行工作

为了回答你的问题,我不认为有一种方法可以取消一个特定的线程本身,但是你可以中断并行。因为不使用取消令牌


请参见MSDN上的以下内容:如何:。

编辑:好的,所以我的第一个想法很糟糕,但这是可行的:

List<string> Items = new List<string>()
{
    "First",
    "Second",
    "Third",
    "Fourth"
};

Parallel.ForEach(Items, (s, t) =>
{
    if (s == "Second")
        return;
    Console.WriteLine(s);
});

我想这会教我不用等待Visual Studio就可以给出答案,经验教训:p

编辑:好的,所以我的第一个想法很糟糕,但这很有效:

List<string> Items = new List<string>()
{
    "First",
    "Second",
    "Third",
    "Fourth"
};

Parallel.ForEach(Items, (s, t) =>
{
    if (s == "Second")
        return;
    Console.WriteLine(s);
});
我想这将教会我在不等待Visual Studio的情况下给出答案,经验教训:p

如前所述,如果您使用Parallel.Foreach或Parallel.for,那么线程池将用于执行代码

为什么不使用Task编写一些类似的功能,但要记住这样的取消

        Action<CancellationToken> work = (token) =>
        {
            Console.WriteLine($"Work started on Thread: {Thread.CurrentThread.ManagedThreadId}");
            foreach (var i in Enumerable.Range(0, 10))
            {
                if (token.IsCancellationRequested)
                {
                    Console.WriteLine($"Work cancelled on Thread: {Thread.CurrentThread.ManagedThreadId}");
                    return;
                }
                Thread.Sleep(1000);
            }
            Console.WriteLine($"Work complete on Thread: {Thread.CurrentThread.ManagedThreadId}");
        };

        var tasks = new List<Tuple<Task, CancellationTokenSource>>();

        foreach (var i in Enumerable.Range(0, 4))
        {
            var cancellation = new CancellationTokenSource();
            var task = Task.Run(() => work(cancellation.Token), cancellation.Token);
            tasks.Add(new Tuple<Task, CancellationTokenSource>(task, cancellation));
        }

        tasks.First().Item2.Cancel();
        Task.WaitAll(tasks.Select(m => m.Item1).ToArray());
这就是您试图实现的目标吗?

如前所述,如果您使用Parallel.Foreach或Parallel.For,那么将使用ThreadPool来执行代码

为什么不使用Task编写一些类似的功能,但要记住这样的取消

        Action<CancellationToken> work = (token) =>
        {
            Console.WriteLine($"Work started on Thread: {Thread.CurrentThread.ManagedThreadId}");
            foreach (var i in Enumerable.Range(0, 10))
            {
                if (token.IsCancellationRequested)
                {
                    Console.WriteLine($"Work cancelled on Thread: {Thread.CurrentThread.ManagedThreadId}");
                    return;
                }
                Thread.Sleep(1000);
            }
            Console.WriteLine($"Work complete on Thread: {Thread.CurrentThread.ManagedThreadId}");
        };

        var tasks = new List<Tuple<Task, CancellationTokenSource>>();

        foreach (var i in Enumerable.Range(0, 4))
        {
            var cancellation = new CancellationTokenSource();
            var task = Task.Run(() => work(cancellation.Token), cancellation.Token);
            tasks.Add(new Tuple<Task, CancellationTokenSource>(task, cancellation));
        }

        tasks.First().Item2.Cancel();
        Task.WaitAll(tasks.Select(m => m.Item1).ToArray());

这就是你想要达到的目标吗?

你能解释一下你真正想要达到的目标是什么吗?您想停止线程还是循环的迭代?如果它真的是一根线,为什么?Parallel.ForEach主要为您管理线程,您不需要做任何类似的事情。您能解释一下您实际上想要完成什么吗?您想停止线程还是循环的迭代?如果它真的是一根线,为什么?Parallel.ForEach主要为您管理线程,您不需要执行类似的操作。不,您不能在Parallel.ForEach中使用continue。等价物只是调用return;或返回本地;从body函数开始,这取决于您是否使用了或。谢谢,我在启动VS并记住Parallel.ForEach的签名中有一个委托时就得到了它。很抱歉方向错误。不,您不能使用并行的continue.foreach。等价物只是调用return;或返回本地;从body函数开始,这取决于您是否使用了或。谢谢,我在启动VS并记住Parallel.ForEach的签名中有一个委托时就得到了它。对不起,误会了。