Why can't use continue or break in Parallel.ForEach in C#?

.net

(Kunni Can) #1

Hi

Recently implemented this :

Parallel.ForEach(_dongles.GetArray(), (dongle) =>
    {
         // The dongle is not connected, then continue.
         if (dongle.IsConnected) continue.
         try {
              dongle.SendCommand("0x01", MyCollection, CMD_12);
         catch (Exception ex) {
              break;// stop on error.
         }
    });

The code above was implemented to solve performance issue using the Parallel feature (multi threading) on this one:

foreach (var dongle in _dongles.GetArray())
    {
         // The dongle is not connected, then continue.
         if (dongle.IsConnected) continue.
         try {
              dongle.SendCommand("0x01", MyCollection, CMD_12);
         catch (Exception ex) {
              break;// stop on error.
         }
    });

The problem though seems to be like continue; and break; are both can’t be used within Parallel.ForEach.

Any ideas?


(Yassine) #2

You are confusing the two Parallel.ForEach method and the C# foreach keyword.

foreach (...) {..}

The foreach block itself, is the one that supports break; and continue; statements according to C# manuals.

Parallel.ForEach()

Parallel.ForEach() on the other hand is just an ordinary C# method which can take the second argument (body) as a lambda method. It doesn’t differ from any other ordinary method in anything it does, except that it can access static variables within the defining method body.

The only flow control statement you can use in a method (lambda) is the return; keyword.

By the way, you must know that as you mentioned Parallel.ForEach() is meant to be a parallel Asynchronous operation, so there is nothing to continue; or break; as theoretically all _dongles.GetArray() members should be accessed at the same instance, thus having a break; or especially a continue; won’t be logical in the first place.


(afree) #3

You should just use return; that’s all.

Parallel.ForEach() is just an ordinary method that’s executing some code in parallel. thus; all you can do is return from that method.

Your code should look something like this:

Parallel.ForEach(_dongles.GetArray(), (dongle) =>
    {
         /* The dongle is not connected, then continue. */
         if (dongle.IsConnected) continue.
         try {
              dongle.SendCommand("0x01", MyCollection, CMD_12);
         catch (Exception ex) {
              return; /*this will break your Parallel.ForEach()*/
         }
    });

In general continue; and break; keywords can only be used within a switch() or loop blocks. And not within an ordinary method even if it’s a Parallel.ForEach().