簡體   English   中英

如何立即終止Parallel.ForEach線程?

[英]How to terminate Parallel.ForEach threads immediately?

我在Parallel.Foreach()調用一些代碼。 該代碼具有Thread.Sleep(60000) ,因此,如果我也取消該令牌,則它會等待60秒,然后再取消Parallel.ForEach循環。 Thread.Sleep()放在此代碼中進行解釋。 實際的代碼具有一些等待其他資源的代碼。 我想取消所有活動為cts.Cancel(); 叫做。

我也嘗試了LoopState,但在我的情況下將不起作用。

 using System;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;

    class Program
    {
        static void Main()
        {
            int[] nums = Enumerable.Range(0, 10000000).ToArray();
            CancellationTokenSource cts = new CancellationTokenSource();

            // Use ParallelOptions instance to store the CancellationToken
            ParallelOptions po = new ParallelOptions();
            po.CancellationToken = cts.Token;
            po.MaxDegreeOfParallelism = System.Environment.ProcessorCount;
            Console.WriteLine("Press any key to start. Press 'c' to cancel.");
            Console.ReadKey();

            // Run a task so that we can cancel from another thread.
            Task.Factory.StartNew(() =>
            {
                if (Console.ReadKey().KeyChar == 'c')
                {
                    cts.Cancel();
                }
                Console.WriteLine("press any key to exit");
            });

            try
            {
                Parallel.ForEach(nums, po, (num) =>
                {
                    double d = Math.Sqrt(num);
                    Console.WriteLine("{0} on {1}", d, Thread.CurrentThread.ManagedThreadId);
                    Thread.Sleep(60000); //Thread Sleep for 1 minute
                    po.CancellationToken.ThrowIfCancellationRequested();
                });
            }
            catch (OperationCanceledException e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                cts.Dispose();
            }

            Console.ReadKey();
        }
    }

如果我理解正確,那么並不是真的需要立即中斷線程,而只是希望能夠在等待狀態時中斷Sleep()方法。

有很多選項,但是最簡單的恕我直言之一是使用CancellationToken.WaitHandle屬性值,然后等待而不是休眠:

po.CancellationToken.WaitHandle.WaitOne(60000);

如果發出令牌信號,則Wait()方法將在指定的超時之前返回(在這種情況下為一分鍾)。

通常,您將檢查返回值,以便可以分辨出發出信號的句柄與等待超時之間的差異,但是在您的情況下,您立即調用po.CancellationToken.ThrowIfCancellationRequested(); ,所以對我來說,僅忽略Wait()方法的返回值並讓下一個程序語句負責實際中斷該方法似乎是合理的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM