1

When I was looked at asynchronous pattern PipeTo for Akka.NET I found example where author uses TaskContinuationOptions and operator &. Is it an erorr or may be it is a propper way to use '&' with Akka.NET and a PipeTo?

For better explain: AttachedToParent & ExecuteSynchronously gave 0 and the inner lambda would be invoked as asyncronosly task.

TaskContinuationOptions.cs

/// When no continuation options are specified, specifies that default behavior should be used when executing a continuation. The continuation runs asynchronously when the antecedent task completes, regardless of the antecedent's final property value. It the continuation is a child task, it is created as a detached nested task.

None = 0,
AttachedToParent = 4,
ExecuteSynchronously = 524288, // 0x00080000

The question should be there "&" or "|" operator?

Denis
  • 833
  • 3
  • 12
  • 22
  • These are bitwise operators that can be applied to enums like these. The keyword you're looking for is something like "enum bit flags" or "bitmask". Here's some documentation: [enum types](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/enum) [bitmasks](https://stackoverflow.com/a/3261485/12258072) Don't confuse `&` (bitwise and) with `&&` (logical and) and the likes. To answer the question (& or |): **usually** | is to have multiple flags and & is to check for a specific flag. – Longoon12000 Jan 03 '20 at 13:14
  • Since `AttachedToParent` and `ExecuteSynchronously` have no bits in common, it does look like the intention was to use `|` and not `&` – canton7 Jan 03 '20 at 13:18
  • As an aside: you can use https://referencesource.microsoft.com to browse the .NET Framework source, and https://source.dot.net to browse the .NET Core source. – canton7 Jan 03 '20 at 13:18
  • 2
    Right, using & makes little sense since that always produces 0 (aka None). Use the Issues section to make the author aware of this. – Hans Passant Jan 03 '20 at 13:21
  • I wrote the sample code the author is linking to - this is a bug in a ~5 year old code sample, not any of the Akka.NET libraries. But I'll go fix it. – Aaronontheweb Jan 04 '20 at 23:59

1 Answers1

4

TL;DR:

Yes. The author should have used | instead of &.

LONG ANSWER:

Bitwise AND => The resulting bit is 1 only if both compared bits are 1.
Bitwise OR => The resulting bit is 1 if any of the two compared bits is 1.

So you first want to translate the numbers to binary (I'll add some 0's to make the comparison easier):

  • 000000 : 00000000000000000000 (None)
  • 000001 : 00000000000000000001 (PreferFairness)
  • 000002 : 00000000000000000010 (LongRunning)
  • 000004 : 00000000000000000100 (AttachedToParent)
  • 065536 : 00010000000000000000 (NotOnRanToCompletion)
  • 131072 : 00100000000000000000 (NotOnFaulted)
  • 196608 : 00110000000000000000 (OnlyOnCanceled)
  • 262144 : 01000000000000000000 (NotOnCanceled)
  • 327680 : 01010000000000000000 (OnlyOnFaulted)
  • 393216 : 01100000000000000000 (OnlyOnFaulted)
  • 524288 : 10000000000000000000 (ExecuteSynchronously)

Now you know, for example, that OnlyOnCanceled is the same as NotOnFaulted+ NotOnRanToCompletion.
Or, using bitwise operators: NotOnFaulted | NotOnRanToCompletion.

On the other hand NotOnFaulted & NotOnRanToCompletion is equal to 0, that corresponds to None.
While OnlyOnCanceled & NotOnFaulted == NotOnRanToCompletion.

So the answer is: when you want to combine, use |. When you want to get the difference, use &.

I hope this example made it clearer.

Alvin Sartor
  • 2,249
  • 4
  • 20
  • 36
  • 1
    That is not his question. The question is if the author of the AkkaDotNet library made a mistake by using `&` to combine two enum flags that have no bits in common and that it really should've been a `|`. – Lasse V. Karlsen Jan 03 '20 at 13:37
  • It is a common mistake because people tend to think "I'll use flag X and Y". – Lasse V. Karlsen Jan 03 '20 at 13:37
  • @LasseV.Karlsen as he asked the question I assumed that he didn't know what was happening. I added a TL;DR section. – Alvin Sartor Jan 03 '20 at 13:41