Skip to content

Commit

Permalink
console application
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelstonis committed Mar 14, 2022
1 parent 3b15777 commit c48a5da
Show file tree
Hide file tree
Showing 3 changed files with 306 additions and 2 deletions.
286 changes: 284 additions & 2 deletions ReactiveDotNetCoreConsole/Program.cs
@@ -1,12 +1,294 @@
using System;
using System.Diagnostics;
using System.Reactive;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Spectre.Console;

namespace ReactiveDotNetCoreConsole
{
class Program
{
static void Main (string[] args)
private readonly static object matlock = new object();

static async Task Main (string[] args)
{
Console.WriteLine("Select an Example");
Console.WriteLine("1a: Publishing With Refcount - Bad");
Console.WriteLine("1b: Publishing With Refcount - Good");
Console.WriteLine("1c: Publishing With Refcount - Good");
Console.WriteLine("2a: Async with Ordering - Bad");
Console.WriteLine("2b: Async with Ordering - Good");
Console.WriteLine("3a: Limit Concurrency - Bad");
Console.WriteLine("3b: Limit Concurrency - Good");
Console.WriteLine("4a: Scheduler - Bad");
Console.WriteLine("4b: Scheduler - Good");

var selection = Console.ReadLine();

switch (selection)
{
case "1a":
await PublishAndRefCountBadExample();
break;
case "1b":
await PublishAndRefCountGoodExample();
break;
case "1c":
await PublishAndRefCountAlternativeGoodExample();
break;
case "2a":
await AsyncOrderingBadExample();
break;
case "2b":
await AsyncOrderingGoodExample();
break;
case "3a":
await LimitConcurrencyBadExample();
break;
case "3b":
await LimitConcurrencyGoodExample();
break;
case "4a":
await SchedulerExampleBad();
break;
case "4b":
await SchedulerExampleGood();
break;
default:
break;
}


Console.WriteLine();
Console.WriteLine("Example Finished. Press Any key to continue...");

Console.ReadLine();
}

public static async Task PublishAndRefCountBadExample ()
{
var intervalObs =
Observable
.Interval(TimeSpan.FromSeconds(2))
.Do(i => WriteToConsoleWithColor((ConsoleColor)i, $"Processing Interval {i}"));

var firstListener =
intervalObs
.Do(val => WriteToConsoleWithColor((ConsoleColor)val, $"First Listener Received: {val}"))
.Subscribe();

var secondListener =
intervalObs
.Do(val => WriteToConsoleWithColor((ConsoleColor)val, $"Second Listener Received: {val}"))
.Subscribe();

await Task.Delay(TimeSpan.FromSeconds(5));

firstListener.Dispose();
secondListener.Dispose();
}

public static async Task PublishAndRefCountGoodExample ()
{
var intervalObs =
Observable
.Interval(TimeSpan.FromSeconds(2))
.Do(i => WriteToConsoleWithColor((ConsoleColor)i, $"Processing Interval {i}"))
.Publish()
.RefCount();

var firstListener =
intervalObs
.Do(val => WriteToConsoleWithColor((ConsoleColor)val, $"First Listener Received: {val}"))
.Subscribe();

var secondListener =
intervalObs
.Do(val => WriteToConsoleWithColor((ConsoleColor)val, $"Second Listener Received: {val}"))
.Subscribe();

await Task.Delay(TimeSpan.FromSeconds(5));

firstListener.Dispose();
secondListener.Dispose();
}

public static async Task PublishAndRefCountAlternativeGoodExample ()
{
var intervalObs =
Observable
.Interval(TimeSpan.FromSeconds(2))
.Do(i => WriteToConsoleWithColor((ConsoleColor)i, $"Processing Interval {i}"))
.Publish();

var firstListener =
intervalObs
.Do(val => WriteToConsoleWithColor((ConsoleColor)val, $"First Listener Received: {val}"))
.Subscribe();

var secondListener =
intervalObs
.Do(val => WriteToConsoleWithColor((ConsoleColor)val, $"Second Listener Received: {val}"))
.Subscribe();

intervalObs.Connect();

await Task.Delay(TimeSpan.FromSeconds(5));

firstListener.Dispose();
secondListener.Dispose();
}

public static async Task AsyncOrderingBadExample ()
{
var rng = new Random();

await Observable
.Range(1, 10, TaskPoolScheduler.Default)
.SelectMany(
async range =>
{
var delay = rng.Next(10, 300);
await Task.Delay(delay);
WriteToConsoleWithColor((ConsoleColor)range, $"{range} - Finished after {delay}ms");
return range;
})
.Do(
range =>
{
WriteToConsoleWithColor((ConsoleColor)range, $"{range} - Received Notification at {DateTimeOffset.Now}");
});
}

public static async Task AsyncOrderingGoodExample()
{
var rng = new Random();

await Observable
.Range(1, 10, TaskPoolScheduler.Default)
.Select(
async range =>
{
var delay = rng.Next(10, 300);
await Task.Delay(delay);
WriteToConsoleWithColor((ConsoleColor)range, $"{range} - Finished after {delay}ms");
return range;
})
.Concat()
.Do(
range =>
{
WriteToConsoleWithColor((ConsoleColor)range, $"{range} - Received Notification at {DateTimeOffset.Now}");
});
}

public static async Task LimitConcurrencyBadExample ()
{
var rng = new Random();

await Observable
.Range(1, 10, TaskPoolScheduler.Default)
.SelectMany(
async range =>
{
WriteToConsoleWithColor((ConsoleColor)range, $"{range} - Started at {DateTimeOffset.Now.ToUnixTimeMilliseconds()}");
var delay = rng.Next(10, 300);
await Task.Delay(delay);
WriteToConsoleWithColor((ConsoleColor)range, $"{range} - Finished after {delay}ms");
return range;
})
.Do(
range =>
{
WriteToConsoleWithColor((ConsoleColor)range, $"{range} - Received Notification at {DateTimeOffset.Now.ToUnixTimeMilliseconds()}");
});
}

public static async Task LimitConcurrencyGoodExample ()
{
var rng = new Random();

await Observable
.Range(1, 10, TaskPoolScheduler.Default)
.Select(
range =>
Observable
.DeferAsync(
async ct =>
{
WriteToConsoleWithColor((ConsoleColor)range, $"{range} - Started at {DateTimeOffset.Now.ToUnixTimeMilliseconds()}");
var delay = rng.Next(10, 300);
await Task.Delay(delay);
WriteToConsoleWithColor((ConsoleColor)range, $"{range} - Finished after {delay}ms");
return Observable.Return(range);
}))
.Merge(1)
.Do(
range =>
{
WriteToConsoleWithColor((ConsoleColor)range, $"{range} - Received Notification at {DateTimeOffset.Now.ToUnixTimeMilliseconds()}");
});
}

public static Task SchedulerExampleBad ()
{
var rng = new Random();

var subscription = Observable
.Range(1, 10)
.Repeat()
.Do(
range =>
{
WriteToConsoleWithColor(
(ConsoleColor)range,
$"{range} - Received Notification at {DateTimeOffset.Now}");
})
.Subscribe();

subscription.Dispose();

return Task.CompletedTask;
}

public static Task SchedulerExampleGood ()
{
var rng = new Random();

var subscription = Observable
.Range(1, 10, TaskPoolScheduler.Default)
.Repeat()
.Do(
range =>
{
WriteToConsoleWithColor(
(ConsoleColor)range,
$"{range} - Received Notification at {DateTimeOffset.Now}");
})
.Subscribe();

subscription.Dispose();

return Task.CompletedTask;
}

private static void WriteToConsoleWithColor(ConsoleColor color, string value)
{
Console.WriteLine("Hello World!");
lock(matlock)
{
Console.ForegroundColor = color;
Console.WriteLine(value);
}
}
}
}
4 changes: 4 additions & 0 deletions ReactiveDotNetCoreConsole/ReactiveDotNetCoreConsole.csproj
Expand Up @@ -5,4 +5,8 @@
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Reactive" Version="5.0.0" />
<PackageReference Include="Spectre.Console" Version="0.21.0" />
</ItemGroup>
</Project>
18 changes: 18 additions & 0 deletions ReactiveExtensionExamples.sln
Expand Up @@ -12,6 +12,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveDotNetCoreApi", "Re
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile", "Mobile", "{E9773837-BF86-46C1-AA2E-C1ECE465C855}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveDotNetCoreConsole", "ReactiveDotNetCoreConsole\ReactiveDotNetCoreConsole.csproj", "{0C92C783-D4CA-405C-9DA8-DF7A7B2AD562}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -88,6 +90,22 @@ Global
{AFB538F3-98AD-479F-93F5-1DF2937F4D06}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{AFB538F3-98AD-479F-93F5-1DF2937F4D06}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{AFB538F3-98AD-479F-93F5-1DF2937F4D06}.AppStore|iPhone.Build.0 = Release|Any CPU
{0C92C783-D4CA-405C-9DA8-DF7A7B2AD562}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0C92C783-D4CA-405C-9DA8-DF7A7B2AD562}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0C92C783-D4CA-405C-9DA8-DF7A7B2AD562}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0C92C783-D4CA-405C-9DA8-DF7A7B2AD562}.Release|Any CPU.Build.0 = Release|Any CPU
{0C92C783-D4CA-405C-9DA8-DF7A7B2AD562}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{0C92C783-D4CA-405C-9DA8-DF7A7B2AD562}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{0C92C783-D4CA-405C-9DA8-DF7A7B2AD562}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{0C92C783-D4CA-405C-9DA8-DF7A7B2AD562}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{0C92C783-D4CA-405C-9DA8-DF7A7B2AD562}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{0C92C783-D4CA-405C-9DA8-DF7A7B2AD562}.Debug|iPhone.Build.0 = Debug|Any CPU
{0C92C783-D4CA-405C-9DA8-DF7A7B2AD562}.Release|iPhone.ActiveCfg = Release|Any CPU
{0C92C783-D4CA-405C-9DA8-DF7A7B2AD562}.Release|iPhone.Build.0 = Release|Any CPU
{0C92C783-D4CA-405C-9DA8-DF7A7B2AD562}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{0C92C783-D4CA-405C-9DA8-DF7A7B2AD562}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{0C92C783-D4CA-405C-9DA8-DF7A7B2AD562}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{0C92C783-D4CA-405C-9DA8-DF7A7B2AD562}.AppStore|iPhone.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{3B2BD6CA-BFCA-4640-940E-624FABAEF8C7} = {E9773837-BF86-46C1-AA2E-C1ECE465C855}
Expand Down

0 comments on commit c48a5da

Please sign in to comment.