using System;
using System.Threading;
using static System.Console;
using static System.Threading.Thread;
namespace Chapter3.Recipe1
{
class Program
{
static void Main(string[] args)
{
int threadId = 0;
RunOnThreadPool poolDelegate = Test;
var t = new Thread(() => Test(out threadId));
t.Start();
t.Join();
WriteLine($"Thread id: {threadId}");
IAsyncResult r = poolDelegate.BeginInvoke(out threadId, Callback, "a delegate asynchronous call");
r.AsyncWaitHandle.WaitOne();
string result = poolDelegate.EndInvoke(out threadId, r);
WriteLine($"Thread pool worker thread id: {threadId}");
WriteLine(result);
Sleep(TimeSpan.FromSeconds(2));
}
private delegate string RunOnThreadPool(out int threadId);
private static void Callback(IAsyncResult ar)
{
WriteLine("Starting a callback...");
WriteLine($"State passed to a callbak: {ar.AsyncState}");
WriteLine($"Is thread pool thread: {CurrentThread.IsThreadPoolThread}");
WriteLine($"Thread pool worker thread id: {CurrentThread.ManagedThreadId}");
}
private static string Test(out int threadId)
{
WriteLine("Starting...");
WriteLine($"Is thread pool thread: {CurrentThread.IsThreadPoolThread}");
Sleep(TimeSpan.FromSeconds(2));
threadId = CurrentThread.ManagedThreadId;
return $"Thread pool worker thread id was: {threadId}";
}
}
}
using System;
using System.Threading;
using static System.Console;
using static System.Threading.Thread;
namespace Chapter3.Recipe2
{
class Program
{
static void Main(string[] args)
{
const int x = 1;
const int y = 2;
const string lambdaState = "lambda state 2";
ThreadPool.QueueUserWorkItem(AsyncOperation);
Sleep(TimeSpan.FromSeconds(1));
ThreadPool.QueueUserWorkItem(AsyncOperation, "async state");
Sleep(TimeSpan.FromSeconds(1));
ThreadPool.QueueUserWorkItem( state =>
{
WriteLine($"Operation state: {state}");
WriteLine($"Worker thread id: {CurrentThread.ManagedThreadId}");
Sleep(TimeSpan.FromSeconds(2));
}, "lambda state");
ThreadPool.QueueUserWorkItem( _ =>
{
WriteLine($"Operation state: {x + y}, {lambdaState}");
WriteLine($"Worker thread id: {CurrentThread.ManagedThreadId}");
Sleep(TimeSpan.FromSeconds(2));
}, "lambda state");
Sleep(TimeSpan.FromSeconds(2));
}
private static void AsyncOperation(object state)
{
WriteLine($"Operation state: {state ?? "(null)"}");
WriteLine($"Worker thread id: {CurrentThread.ManagedThreadId}");
Sleep(TimeSpan.FromSeconds(2));
}
}
}
using System;
using System.Diagnostics;
using System.Threading;
using static System.Console;
using static System.Threading.Thread;
namespace Chapter3.Recipe3
{
class Program
{
static void Main(string[] args)
{
const int numberOfOperations = 500;
var sw = new Stopwatch();
sw.Start();
UseThreads(numberOfOperations);
sw.Stop();
WriteLine($"Execution time using threads: {sw.ElapsedMilliseconds}");
sw.Reset();
sw.Start();
UseThreadPool(numberOfOperations);
sw.Stop();
WriteLine($"Execution time using the thread pool: {sw.ElapsedMilliseconds}");
}
static void UseThreads(int numberOfOperations)
{
using (var countdown = new CountdownEvent(numberOfOperations))
{
WriteLine("Scheduling work by creating threads");
for (int i = 0; i < numberOfOperations; i++)
{
var thread = new Thread(() =>
{
Write($"{CurrentThread.ManagedThreadId},");
Sleep(TimeSpan.FromSeconds(0.1));
countdown.Signal();
});
thread.Start();
}
countdown.Wait();
WriteLine();
}
}
static void UseThreadPool(int numberOfOperations)
{
using (var countdown = new CountdownEvent(numberOfOperations))
{
WriteLine("Starting work on a threadpool");
for (int i = 0; i < numberOfOperations; i++)
{
ThreadPool.QueueUserWorkItem( _ =>
{
Write($"{CurrentThread.ManagedThreadId},");
Sleep(TimeSpan.FromSeconds(0.1));
countdown.Signal();
});
}
countdown.Wait();
WriteLine();
}
}
}
}
using System;
using System.Threading;
using static System.Console;
using static System.Threading.Thread;
namespace Chapter3.Recipe4
{
class Program
{
static void Main(string[] args)
{
using (var cts = new CancellationTokenSource())
{
CancellationToken token = cts.Token;
ThreadPool.QueueUserWorkItem(_ => AsyncOperation1(token));
Sleep(TimeSpan.FromSeconds(2));
cts.Cancel();
}
using (var cts = new CancellationTokenSource())
{
CancellationToken token = cts.Token;
ThreadPool.QueueUserWorkItem(_ => AsyncOperation2(token));
Sleep(TimeSpan.FromSeconds(2));
cts.Cancel();
}
using (var cts = new CancellationTokenSource())
{
CancellationToken token = cts.Token;
ThreadPool.QueueUserWorkItem(_ => AsyncOperation3(token));
Sleep(TimeSpan.FromSeconds(2));
cts.Cancel();
}
Sleep(TimeSpan.FromSeconds(2));
}
static void AsyncOperation1(CancellationToken token)
{
WriteLine("Starting the first task");
for (int i = 0; i < 5; i++)
{
if (token.IsCancellationRequested)
{
WriteLine("The first task has been canceled.");
return;
}
Sleep(TimeSpan.FromSeconds(1));
}
WriteLine("The first task has completed succesfully");
}
static void AsyncOperation2(CancellationToken token)
{
try
{
WriteLine("Starting the second task");
for (int i = 0; i < 5; i++)
{
token.ThrowIfCancellationRequested();
Sleep(TimeSpan.FromSeconds(1));
}
WriteLine("The second task has completed succesfully");
}
catch (OperationCanceledException)
{
WriteLine("The second task has been canceled.");
}
}
static void AsyncOperation3(CancellationToken token)
{
bool cancellationFlag = false;
token.Register(() => cancellationFlag = true);
WriteLine("Starting the third task");
for (int i = 0; i < 5; i++)
{
if (cancellationFlag)
{
WriteLine("The third task has been canceled.");
return;
}
Sleep(TimeSpan.FromSeconds(1));
}
WriteLine("The third task has completed succesfully");
}
}
}
using System;
using System.Threading;
using static System.Console;
using static System.Threading.Thread;
namespace Chapter3.Recipe5
{
class Program
{
static void Main(string[] args)
{
RunOperations(TimeSpan.FromSeconds(5));
RunOperations(TimeSpan.FromSeconds(7));
}
static void RunOperations(TimeSpan workerOperationTimeout)
{
using (var evt = new ManualResetEvent(false))
using (var cts = new CancellationTokenSource())
{
WriteLine("Registering timeout operation...");
var worker = ThreadPool.RegisterWaitForSingleObject(evt
, (state, isTimedOut) => WorkerOperationWait(cts, isTimedOut)
, null
, workerOperationTimeout
, true);
WriteLine("Starting long running operation...");
ThreadPool.QueueUserWorkItem(_ => WorkerOperation(cts.Token, evt));
Sleep(workerOperationTimeout.Add(TimeSpan.FromSeconds(2)));
worker.Unregister(evt);
}
}
static void WorkerOperation(CancellationToken token, ManualResetEvent evt)
{
for(int i = 0; i < 6; i++)
{
if (token.IsCancellationRequested)
{
return;
}
Sleep(TimeSpan.FromSeconds(1));
}
evt.Set();
}
static void WorkerOperationWait(CancellationTokenSource cts, bool isTimedOut)
{
if (isTimedOut)
{
cts.Cancel();
WriteLine("Worker operation timed out and was canceled.");
}
else
{
WriteLine("Worker operation succeded.");
}
}
}
}
using System;
using System.Threading;
using static System.Console;
using static System.Threading.Thread;
namespace Chapter3.Recipe6
{
class Program
{
static void Main(string[] args)
{
WriteLine("Press 'Enter' to stop the timer...");
DateTime start = DateTime.Now;
_timer = new Timer(_ => TimerOperation(start), null
, TimeSpan.FromSeconds(1)
, TimeSpan.FromSeconds(2));
try
{
Sleep(TimeSpan.FromSeconds(6));
_timer.Change(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(4));
ReadLine();
}
finally
{
_timer.Dispose();
}
}
static Timer _timer;
static void TimerOperation(DateTime start)
{
TimeSpan elapsed = DateTime.Now - start;
WriteLine($"{elapsed.Seconds} seconds from {start}. " +
$"Timer thread pool thread id: {CurrentThread.ManagedThreadId}");
}
}
}
using System;
using System.ComponentModel;
using static System.Console;
using static System.Threading.Thread;
namespace Chapter3.Recipe7
{
class Program
{
static void Main(string[] args)
{
var bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
bw.DoWork += Worker_DoWork;
bw.ProgressChanged += Worker_ProgressChanged;
bw.RunWorkerCompleted += Worker_Completed;
bw.RunWorkerAsync();
WriteLine("Press C to cancel work");
do
{
if (ReadKey(true).KeyChar == 'C')
{
bw.CancelAsync();
}
}
while(bw.IsBusy);
}
static void Worker_DoWork(object sender, DoWorkEventArgs e)
{
WriteLine($"DoWork thread pool thread id: {CurrentThread.ManagedThreadId}");
var bw = (BackgroundWorker) sender;
for (int i = 1; i <= 100; i++)
{
if (bw.CancellationPending)
{
e.Cancel = true;
return;
}
if (i%10 == 0)
{
bw.ReportProgress(i);
}
Sleep(TimeSpan.FromSeconds(0.1));
}
e.Result = 42;
}
static void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
WriteLine($"{e.ProgressPercentage}% completed. " +
$"Progress thread pool thread id: {CurrentThread.ManagedThreadId}");
}
static void Worker_Completed(object sender, RunWorkerCompletedEventArgs e)
{
WriteLine($"Completed thread pool thread id: {CurrentThread.ManagedThreadId}");
if (e.Error != null)
{
WriteLine($"Exception {e.Error.Message} has occured.");
}
else if (e.Cancelled)
{
WriteLine($"Operation has been canceled.");
}
else
{
WriteLine($"The answer is: {e.Result}");
}
}
}
}