How do I block the current thread until the OnComplete
handler of my observer has finished, without the use of threading primitives?
Here is my code. I want that the Console.WriteLine("Press...
statement should be executed only after the OnComplete
handler, namely ResetCount
has finished executing.
class Program
{
private static long totalItemCount = 0;
private static long listCount = 0;
static void Main()
{
Console.WriteLine($"Starting Main on Thread {Thread.CurrentThread.ManagedThreadId}\n");
var o = Observable.Timer(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(1))
.Take(20)
.Concat(Observable.Interval(TimeSpan.FromSeconds(0.01)).Take(200))
.Buffer(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5));
o.Subscribe(Print, onCompleted: ResetCount);
// How I make sure this line appears only after the OnComplete has fired?
// Do I have to use traditional threading primitives such as wait handles?
// Or just cause the main thread to sleep long enough? That doesn't seem right.
Console.WriteLine("\nPress any key to exit...");
Console.ReadKey();
}
private static void ResetCount()
{
if (listCount > 0)
{
Console.WriteLine($"{totalItemCount} items processed in {listCount} lists.");
}
else
{
Console.WriteLine($"{totalItemCount} items processed.");
}
Interlocked.Exchange(ref totalItemCount, 0);
Interlocked.Exchange(ref listCount, 0);
}
static void Print<T>(T value)
{
var threadType = Thread.CurrentThread.IsBackground ? "Background" : "Foreground";
if (value is IList)
{
var list = value as IList;
Console.WriteLine($"{list.Count} items in list #{Interlocked.Increment(ref listCount)}:");
foreach (var item in list)
{
Console.WriteLine($"{item.ToString()}, ({threadType} #{Thread.CurrentThread.ManagedThreadId}), Item #{Interlocked.Increment(ref totalItemCount)}");
}
Console.WriteLine();
}
else
{
Console.WriteLine($"{value.ToString()}, ({threadType} #{Thread.CurrentThread.ManagedThreadId}), Item #{Interlocked.Increment(ref totalItemCount)}");
}
}
}