Skip to content

Instantly share code, notes, and snippets.

@ssomers
Last active September 4, 2020 13:08
Show Gist options
  • Save ssomers/17c961ff80b17955fd8674d191d2c149 to your computer and use it in GitHub Desktop.
Save ssomers/17c961ff80b17955fd8674d191d2c149 to your computer and use it in GitHub Desktop.
Task.Run differs from Task.Factory.StartNew with TaskCreationOptions.DenyChildAttach & TaskScheduler.Default
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
internal static class Program
{
private static void Main()
{
var chan = new BufferBlock<int>(new DataflowBlockOptions { BoundedCapacity = 2 });
Task.Factory.StartNew(async () =>
{
for (int i = 1; i <= 4; ++i)
{
while (!chan.Post(i)) await Task.Delay(10);
Console.WriteLine($"produced {i}");
}
chan.Complete();
Console.WriteLine("stop producing");
},
CancellationToken.None,
TaskCreationOptions.DenyChildAttach,
TaskScheduler.Default);
var task = Task.Factory.StartNew(async () =>
{
try
{
while (true)
{
int i = await chan.ReceiveAsync();
Console.WriteLine($"consumed {i}");
}
}
catch (InvalidOperationException)
{
Console.WriteLine("stop consuming");
}
},
CancellationToken.None,
TaskCreationOptions.DenyChildAttach,
TaskScheduler.Default);
task.Wait();
Console.WriteLine("stop waiting");
Thread.Sleep(2020);
}
}
@ssomers
Copy link
Author

ssomers commented Sep 4, 2020

When run as a console app, this output for instance:

produced 1
produced 2
consumed 1
consumed 2
stop waiting
produced 3
produced 4
stop producing
consumed 3
consumed 4
stop consuming

suggesting that the 2nd task continues after it has ended.

Replace Task.Factory.StartNew with Task.Run and delete the 3 extra arguments, and the output starts making sense.

Adding a .Unwrap() after the StartNew(...) instead gives the same reasonable output.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment