簡體   English   中英

Parallel.Foreach循環永無止境

[英]Parallel.Foreach loop never ends

我的代碼在較小的循環上可以按預期執行,但是當我遍歷較大的IP范圍時,該過程似乎會短暫停止並且永遠不會完成。

該程序將繼續運行,並且不會引發任何異常。

public void Discover()
{
    Int32 MaxThreadCount     = 20, 
        DevicesProcessed     = 0;
    List<String> IPAddresses = GetIPAddresses(IPRangesToCheck).ToList();

    using (cts = new CancellationTokenSource())
    {

        ParallelOptions po = new ParallelOptions();
        po.MaxDegreeOfParallelism = MaxThreadCount;
        po.CancellationToken = cts.Token;

        try
        {
            var deviceInfo = new DeviceInfo();

            Parallel.ForEach(IPAddresses, po, (item, loopState) =>
            {
                try
                {
                    Console.WriteLine("DevicesProcessed: {0}, IPAddresses.Count: {1}", DevicesProcessed, IPAddresses.Count.ToString());
                    if (DevicesProcessed >= IPAddresses.Count)
                    {
                        Console.WriteLine("!!!THRESHOLD REACHED!!!");
                        cts.Cancel();
                    }

                    if (loopState.ShouldExitCurrentIteration || loopState.IsExceptional)
                    {
                        loopState.Stop();
                        DiscoverStatus = Devices.DiscoverState.Stopped;
                    }

                    var response = CheckIPAndReturnInfo(item);

                    if (loopState.ShouldExitCurrentIteration || loopState.IsExceptional)
                    {
                        loopState.Stop();
                        DiscoverStatus = Devices.DiscoverState.Stopped;
                    }

                    if (response != null)
                    {
                        FoundDevices.Add(response);
                        Console.WriteLine(
                            "Device Count {0}, IP Address {1}",
                            DevicesProcessed,
                            item);
                    }

                    Interlocked.Increment(ref DevicesProcessed);
                }
                catch (Exception ex)
                {
                    Console.Write("Error! = " + ex.Message);

                    if (deviceInfo.State == CommunicationState.Faulted)
                    {
                        loopState.Stop();
                    }
                }
            });

            RaiseAllItemsCompleteEvent();

        }
        catch (AggregateException aggEx)
        {
            Console.WriteLine("Parrallel Exception!: " + aggEx);
        }
    }
}

當我使用172.16.0.0到172.16.255.255范圍時,有65536個IP地址需要檢查。 在停止處理更多的地址之前,程序進入65519,並且在代碼中未進行進一步的處理。 此時,在代碼中的任何地方都沒有命中斷點。

if (DevicesProcessed >= IPAddresses.Count)部分是嘗試在循環結束后手動取消該循環,但是不幸的是,循環並沒有走多遠。 在此之前,請先取消操作。

我一直找不到其他人遇到與此並行任務有關的問題,對此我感到很沮喪。 關於進一步調試問題的方法的任何建議將不勝感激。

我在CheckIPAndReturnInfo類中添加了一個秒表,以查看經過多長時間。 這是生成“ Start:和“ End:輸出文本的地方。 這是程序輸出的輸出示例:

DevicesProcessed: 65515, IPAddresses.Count: 65536
Start : 172.16.114.94
End : 172.16.114.94 Elaspsed: 00:00:01.4247110
A first chance exception of type 'System.Net.Sockets.SocketException' occurred in System.dll
A first chance exception of type 'Lextm.SharpSnmpLib.Messaging.TimeoutException' occurred in SharpSnmpLib.dll
End : 172.16.114.60 Elaspsed: 00:00:07.0803977
DevicesProcessed: 65517, IPAddresses.Count: 65536
Start : 172.16.114.61
A first chance exception of type 'Lextm.SharpSnmpLib.Messaging.TimeoutException' occurred in SharpSnmpLib.dll
End : 172.16.114.76 Elaspsed: 00:00:07.0807436
DevicesProcessed: 65518, IPAddresses.Count: 65536
Start : 172.16.114.77
A first chance exception of type 'Lextm.SharpSnmpLib.Messaging.TimeoutException' occurred in SharpSnmpLib.dll
The thread '<No Name>' (0x1664) has exited with code 0 (0x0).
A first chance exception of type 'Lextm.SharpSnmpLib.Messaging.TimeoutException' occurred in SharpSnmpLib.dll
A first chance exception of type 'Lextm.SharpSnmpLib.Messaging.TimeoutException' occurred in SharpSnmpLib.dll
End : 172.16.114.61 Elaspsed: 00:00:07.0806001
DevicesProcessed: 65519, IPAddresses.Count: 65536
Start : 172.16.114.62
A first chance exception of type 'Lextm.SharpSnmpLib.Messaging.TimeoutException' occurred in SharpSnmpLib.dll
End : 172.16.114.77 Elaspsed: 00:00:07.0807928
DevicesProcessed: 65520, IPAddresses.Count: 65536
Start : 172.16.114.78
A first chance exception of type 'Lextm.SharpSnmpLib.Messaging.TimeoutException' occurred in SharpSnmpLib.dll
The thread '<No Name>' (0xf90) has exited with code 0 (0x0).
The thread '<No Name>' (0x1b24) has exited with code 0 (0x0).
A first chance exception of type 'System.Net.Sockets.SocketException' occurred in System.dll
A first chance exception of type 'Lextm.SharpSnmpLib.Messaging.TimeoutException' occurred in SharpSnmpLib.dll
A first chance exception of type 'Lextm.SharpSnmpLib.Messaging.TimeoutException' occurred in SharpSnmpLib.dll
End : 172.16.114.62 Elaspsed: 00:00:07.0806679
A first chance exception of type 'Lextm.SharpSnmpLib.Messaging.TimeoutException' occurred in SharpSnmpLib.dll
End : 172.16.114.78 Elaspsed: 00:00:07.0804395
The thread '<No Name>' (0x1518) has exited with code 0 (0x0).
The thread '<No Name>' (0x1e1c) has exited with code 0 (0x0).
The thread '<No Name>' (0x1190) has exited with code 0 (0x0).
The thread '<No Name>' (0x1218) has exited with code 0 (0x0).
The thread '<No Name>' (0x1c68) has exited with code 0 (0x0).
The thread '<No Name>' (0x1b20) has exited with code 0 (0x0).
The thread '<No Name>' (0xa14) has exited with code 0 (0x0).
The thread '<No Name>' (0x185c) has exited with code 0 (0x0).
The thread '<No Name>' (0x430) has exited with code 0 (0x0).
  1. 不要在if語句中使用IsCompleted 只要把RaiseAllItemsCompleteEventParallel.ForEach

  2. 在您的異常處理程序中,請勿重新引發異常,因為這將導致Parallel出錯。 只需使用loopState.Stop

愚蠢的例子:

Parallel.ForEach(Enumerable.Range(0, 100),
    (i, state) =>
    {
        Console.WriteLine(i);
        if(i==11) state.Stop();
    });
RaiseAllItemsCompleteEvent();

在條件檢查中,只需使用if(loopState.IsStopped) 給定您的try/catch塊,很難擊中IsExceptional

最后,因為您正在並行運行,所以必須使用Interlocked.Increment(ref DevicesProcessed) 否則,計數將不准確。

cts.Cancel()可以拋出AggregateException

也可以在內部嘗試捕獲它,看看它是否命中,如果這是在您當前的代碼中沒有內部`AggregateException'發生的,它將進入無限循環。

暫無
暫無

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

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