Im making a app that monitors stuff on my computer, and i want to make it somewhat more difficult then just implementing a while loop.
So my question is how do i do it if i would like to fetch cpu load in a seperate thread, that updates a static variable in class
namespace threads
{
class Program
{
static int cpuload = 0;
static void Main(string[] args)
{
while (true)
{
Thread th = new Thread(new ThreadStart(CheckCPULoad));
th.Start();
Thread.Sleep(1000); // sleep the main thread
th.Abort();
Console.WriteLine("load: {0}%", cpuload);
}
}
static void CheckCPULoad()
{
// things are updated every 3 secs, dummy data
Thread.Sleep(3000);
Random rnd = new Random();
cpuload++;// = rnd.Next(0, 100); // dummy data
}
}
}
As it is "load: 0%" is printed every time. what do i need to fix to make it show
load: 0%
load: 0%
load: 0%
?
thanks
In order to "report back" to the main thread, the main thread has to be "listening". Which means, still running in a while loop and checking some kind of a queue for new items that represent the reports.
What you basically need is a queue where the worker thread will put its reports, and the main thread will periodically check this queue for reports from the worker.
You have two main approaches:
A blocking queue. Means that when
there are no items the caller thread
blocks until items arrive. This is
good if the main thread has nothing
to do except wait for items in the
queue.
A non-blocking queue. Means that it
returns immediately to the caller
regardless of the items count. This
is good if you want your main thread
to be busy doing stuff and sometimes
checking the queue for reports.
If your application is a UI application you automatically get the first approach, as this is how the UI works. To add "an item" you can use Control.BeginInvoke (in winforms) or Dispatcher.BeginInvoke (in wpf).
If i get you right, this should solve your purpose. Notice the while loop inside the CheckCPULoad() method.
class Program
{
static int cpuload = 0;
static void Main(string[] args)
{
Thread th = new Thread(new ThreadStart(CheckCPULoad));
th.Start();
while (true)
{
Thread.Sleep(1000);
Console.WriteLine("load: {0}%", cpuload);
}
th.Abort(); // Don't ever reach this line with while (true)
}
static void CheckCPULoad()
{
while (true)
{
Thread.Sleep(3000);
cpuload++;
}
}
}
The code you're using there starts the CheckCPULoad thread, waits 1 second and then aborts it. However, the first thing the CheckCPULoad thread does is to sleep for 3 seconds. So you never actually reach the cpuload++ instruction. I suspect this would be closer to what you intended:
namespace threads
{
class Program
{
static int cpuload = 0;
static void Main(string[] args)
{
Thread th = new Thread(new ThreadStart(CheckCPULoad));
th.Start();
while (true)
{
Thread.Sleep(1000);
Console.WriteLine("load: {0}%", cpuload);
}
th.Abort(); // Don't ever reach this line with while (true)
}
static void CheckCPULoad()
{
while (true)
{
Thread.Sleep(3000);
cpuload++;
}
}
}
}
Use a timer and events instead. This way you avoid your sleeping/busy waiting. Also consider using Interlocked.Increment as suggested if several threads can modify the static variable at the same time.
using System;
using System.Threading;
using System.Timers;
using Timer = System.Timers.Timer;
namespace CpuLoad
{
internal class Program
{
private static int cpuload;
private static readonly AutoResetEvent autoEvent = new AutoResetEvent(false);
private static void Main(string[] args)
{
var timer = new Timer(3000);
timer.Elapsed += CheckCPULoad;
timer.Start();
while (true)
{
autoEvent.WaitOne();
autoEvent.Reset();
Console.WriteLine(cpuload);
}
}
private static void CheckCPULoad(object sender, ElapsedEventArgs e)
{
cpuload++;
autoEvent.Set();
}
}
}
Instead of cpuload++ try using
Interlocked.Increment(ref cpuload);
Check - http://msdn.microsoft.com/en-us/library/dd78zt0c.aspx
The thread sleeps for 3 secs. You abort it after 1. Go figure :)
With callback you can do that
here is an exsample:
public class Example2
{
// Declaration - Take 1 parameter, return nothing
public delegate void LogHandler(string message);
// Instantiation - Create a function which takes delegate as one parameter
// Verify if it is null before you use it
public void Process(LogHandler logHandler)
{
if (logHandler != null)
{
logHandler("Process() begin");
}
if (logHandler != null)
{
logHandler("Process() end");
}
}
}
public class Example2DelegateConsumer
{
// Create a method with the same signature as the delegate
static void Logger(string s)
{
Console.WriteLine(s);
}
public static void Main(string[] args)
{
Example2 ex2 = new Example2();
// Invocation in the client
Example2.LogHandler myLogger = new Example2.LogHandler(Logger);
ex2.Process(myLogger);
}
}
In addition to my original (plagiarised) answer below, this sort of situation where you're observing a set of values over time is a great fit for Reactive Extensions for .NET (http://blogs.msdn.com/b/rxteam/). You can get the desired effect with Rx thus:
static void Main()
{
var cpuLoadSequence = Observable.GenerateWithTime(
0, // initial value
i => true, // continue forever
i => i + 1, // increment value
i => i, // result = value
i => TimeSpan.FromSeconds(3)); // delay 3 seconds
using (cpuLoadSequence.Subscribe(x => Console.WriteLine("load: {0}%", x)))
{
Console.WriteLine("Press ENTER to stop.");
Console.ReadLine();
}
}
Related
I'd like to pause for a file update (can take a few seconds) using Thread.Sleep loop that checks every second for timestamp change. However, the app freezes completely during the sleep loop and can't even refresh the display.
I looked into the following (simplified) code which doesn't freeze the program. But the program reaches the end (prints "Done") before the Worker function ends - wait for the func to complete (print "end" before "done"). Unremarked the last line, to wait for the func's end, freezes the app.
Is there a better way to wait for file change without freezing the app? If not, how to wait for a lengthy function to complete without freezing the app AND waiting for the func to finish before commencing with the main code?
private static ManualResetEvent resetEvent = new ManualResetEvent(false);
private void Worker(object ignored)
{
Print("start");
Thread.Sleep(5000);
Print("end")
resetEvent.Set();
}
Main:
ThreadPool.QueueUserWorkItem(new WaitCallback(Worker));
Print("Done");
//resetEvent.WaitOne();
output with the last line remarked:
Done
start
end
output with last line unremarked:
(app freezes, then):
1. Start
2. End
3. Done
expected, without freezing:
start
end
Done
As I mentioned in comments the right way would be to use async/await. The code will look like this:
private async Task Worker()
{
Print("start");
await Task.Delay(5000);
Print("end");
}
main:
public async void DoSomething()
{
await Worker();
Print("Done");
}
If you want to use ThreadPool directly. Base on platform you may need to provide a Dispatcher to Worker method so it call a method to execute in initial thread.
I like waiting with Semaphores. Check out the overloaded method WaitOne.
using System;
using System.Threading;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
Semaphore mutex = new Semaphore(0, 1);
Thread t = new Thread(() => {
Console.WriteLine("Hello from another thread");
Console.ReadLine();
mutex.Release();
});
t.Start();
while (!mutex.WaitOne(1000))
Console.WriteLine("Waiting " + 1 + " sec");
Console.WriteLine("Hello from main thread");
Console.ReadLine();
}
}
}
Assuming you are working with Winforms, one solution is this:
class Foo
{
bool spin;
void Worker()
{
Print("start");
///Do job
Print("end")
spin=false;
}
void mainMethod()
{
spin = true;
ThreadPool.QueueUserWorkItem(new WaitCallback(Worker));
while(spin)
{
Thread.Sleep(500);
Application.DoEvents();
}
}
}
Usually I avoid using Thread.Sleep except for testing or debugging code.
In the following example, I'm trying to run a console app which will run different classes that will trigger timer ticks at certain times. The idea is to add many more classes that run independent services.
At the moment I'm using, Thread.Sleep(10000); just to keep the console open to allow the code to run.
Surely the Thread.Sleep is blocking some resouces of the CPU?
Is there a better way? (This would be for both Windows and Linux)
while(true)
{
Thread.Sleep(10000);
}
Program:
class Program
{
private static CultureInfo culture = new CultureInfo("en-gb");
static void Main(string[] args)
{
LongRunningClass longRunningClass = new LongRunningClass();
while(true)
{
Thread.Sleep(10000);
}
}
}
Long Running Task:
public class LongRunningClass
{
private Timer timer;
private List<TimeSpan> ScheduleTimes = new List<TimeSpan>()
{
new TimeSpan(4,0,0),
new TimeSpan(6,0,0),
new TimeSpan(21,0,0),
new TimeSpan(23,0,0),
};
public LongRunningClass()
{
this.timer = new Timer(1000);
this.timer.Elapsed += new ElapsedEventHandler(OnTick);
this.timer.Start();
}
protected virtual void OnTick(object sender, ElapsedEventArgs e)
{
this.timer.Stop();
RunLongRunningTask();
double nextTickInterval = 0;
TimeSpan timeOfDayNow = DateTime.Now.TimeOfDay;
foreach (TimeSpan scheduleTime in ScheduleTimes)
{
if (scheduleTime > timeOfDayNow)
{
nextTickInterval = (scheduleTime - timeOfDayNow).TotalMilliseconds;
break;
}
}
// If tick interval not set yet then restart for next day
if (nextTickInterval <= 0)
{
TimeSpan scheduleTime = ScheduleTimes[0].Add(new TimeSpan(1, 0, 0, 0));
nextTickInterval = (scheduleTime - timeOfDayNow).TotalMilliseconds;
}
this.timer.Interval = nextTickInterval;
this.timer.Start();
}
private void RunLongRunningTask()
{
// Long Running Task
}
}
If it's about keeping the console open.
Did you try?
while(true)
{
Console.Read();
}
or just:
Console.Read();
so, it wouldn't close unless you press a key.
You can keep the console open indefinitely until the user cancels by using an AutoResetEvent:
class Program
{
private static AutoResetEvent autoResetEvent;
private static CultureInfo culture = new CultureInfo("en-gb");
static void Main(string[] args)
{
LongRunningClass longRunningClass = new LongRunningClass();
WaitForCancel();
}
/// <summary>
/// When cancel keys Ctrl+C or Ctrl+Break are used, set the event.
/// </summary>
private static void WaitForCancel()
{
autoResetEvent = new AutoResetEvent(false);
Console.WriteLine("Press CTRL + C or CTRL + Break to exit...");
Console.CancelKeyPress += (sender, e) =>
{
e.Cancel = true;
autoResetEvent.Set();
};
autoResetEvent.WaitOne();
}
}
Obviously, this method relies on you knowing when your threads have finished processing.
Surely the Thread.Sleep is blocking some resouces of the CPU?
Its not the CPU you have to worry about, its the memory. You can read the complicated version here, but the simple version is that each thread uses 1MB of memory for the stack. If you are writing an application which needs a lot of threads then you should consider writing async Methods and using Task.Delay. This allows the thread to do something else while the method is waiting, which can reduce the total number of threads needed to process the same workload.
In this case however there isn't much point - while C# 7.1 does support async Main, its just syntactic sugar and doesn't free the thread up to perform other work. In any case I wouldn't loose sleep over using Thread.Sleep in a simple console app like this, or alternatively using something like Console.ReadLine like Neos07 suggests.
Thread.Sleep does still work, but you can consider using Task.Delay as an alternative here, like
await Task.Delay(1000);
I have a timer calling a function every 15 minutes, this function counts the amount of lines in my DGV and starts a thread for each lines (of yet another function), said thread parse a web page which can take anywhere from 1 second to 10 second to finish.
Whilst it does work fine as it is with 1-6 rows, anymore will cause the requests to time-out.
I want it to wait for the newly created thread to finish processing before getting back in the loop to create another thread without locking the main UI
for (int x = 0; x <= dataGridFollow.Rows.Count - 1; x++)
{
string getID = dataGridFollow.Rows[x].Cells["ID"].Value.ToString();
int ID = int.Parse(getID);
Thread t = new Thread(new ParameterizedThreadStart(UpdateLo));
t.Start(ID);
// <- Wait for thread to finish here before getting back in the for loop
}
I have googled a lot in the past 24 hours, read a lot about this specific issue and its implementations (Thread.Join, ThreadPools, Queuing, and even SmartThreadPool).
It's likely that I've read the correct answer somewhere but I'm not at ease enough with C# to decypher those Threading tools
Thanks for your time
to avoid the UI freeze the framework provide a class expressly for these purposes: have a look at the BackgroundWorker class (executes an operation on a separate thread), here's some infos : http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
http://msdn.microsoft.com/en-us/magazine/cc300429.aspx
Btw looks if I understand correctly you don't want to parallelize any operation so just wait for the method parsing the page to be completed. Basically for each (foreach look) row of your grid you get the id and call the method. If you want to go parallel just reuse the same foreach loop and add make it Parallel
http://msdn.microsoft.com/en-us/library/dd460720.aspx
What you want is to set off a few workers that do some task.
When one finishes you can start a new one off.
I'm sure there is a better way using thread pools or whatever.. but I was bored so i came up with this.
using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;
using System.Threading;
namespace WorkerTest
{
class Program
{
static void Main(string[] args)
{
WorkerGroup workerGroup = new WorkerGroup();
Console.WriteLine("Starting...");
for (int i = 0; i < 100; i++)
{
var work = new Action(() =>
{
Thread.Sleep(1000); //somework
});
workerGroup.AddWork(work);
}
while (workerGroup.WorkCount > 0)
{
Console.WriteLine(workerGroup.WorkCount);
Thread.Sleep(1000);
}
Console.WriteLine("Fin");
Console.ReadLine();
}
}
public class WorkerGroup
{
private List<Worker> workers;
private Queue<Action> workToDo;
private object Lock = new object();
public int WorkCount { get { return workToDo.Count; } }
public WorkerGroup()
{
workers = new List<Worker>();
workers.Add(new Worker());
workers.Add(new Worker());
foreach (var w in workers)
{
w.WorkCompleted += (OnWorkCompleted);
}
workToDo = new Queue<Action>();
}
private void OnWorkCompleted(object sender, EventArgs e)
{
FindWork();
}
public void AddWork(Action work)
{
workToDo.Enqueue(work);
FindWork();
}
private void FindWork()
{
lock (Lock)
{
if (workToDo.Count > 0)
{
var availableWorker = workers.FirstOrDefault(x => !x.IsBusy);
if (availableWorker != null)
{
var work = workToDo.Dequeue();
availableWorker.StartWork(work);
}
}
}
}
}
public class Worker
{
private BackgroundWorker worker;
private Action work;
public bool IsBusy { get { return worker.IsBusy; } }
public event EventHandler WorkCompleted;
public Worker()
{
worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(OnWorkerDoWork);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(OnWorkerRunWorkerCompleted);
}
private void OnWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (WorkCompleted != null)
{
WorkCompleted(this, EventArgs.Empty);
}
}
public void StartWork(Action work)
{
if (!IsBusy)
{
this.work = work;
worker.RunWorkerAsync();
}
else
{
throw new InvalidOperationException("Worker is busy");
}
}
private void OnWorkerDoWork(object sender, DoWorkEventArgs e)
{
work.Invoke();
work = null;
}
}
}
This would be just a starting point.
You could start it off with a list of Actions and then have a completed event for when that group of actions is finished.
then at least you can use a ManualResetEvent to wait for the completed event.. or whatever logic you want really.
Call a method directly or do a while loop (with sleep calls) to check the status of the thread.
There are also async events but the would call another method, and you want to continue from the same point.
I have no idea why the requests would timeout. That sounds like a different issue. However, I can make a few suggestions regarding your current approach.
Avoid creating threads in loops with nondeterministic bounds. There is a lot of overhead in creating threads. If the number of operations is not known before hand then use the ThreadPool or the Task Parallel Library instead.
You are not going to get the behavior you want by blocking the UI thread with Thread.Join. The cause the UI to become unresponsive and it will effectively serialize the operations and cancel out any advantage you were hoping to gain with threads.
If you really want to limit the number of concurrent operations then a better solution is to create a separate dedicated thread for kicking off the operations. This thread will spin around a loop indefinitely waiting for items to appear in a queue and when they do it will dequeue them and use that information to kick off an operation asynchronously (again using the ThreadPool or TPL). The dequeueing thread can contain the logic for limiting the number of concurrent operations. Search for information regarding the producer-consumer pattern to get a better understand of how you can implement this.
There is a bit of a learning curve, but who said threading was easy right?
If I understand correctly, what you're currently doing is looping through a list of IDs in the UI thread, starting a new thread to handle each one. The blocking issue you're seeing then could well be that it's taking too many resources to create unique threads. So, personally (without knowing more) would redesign the process like so:
//Somewhere in the UI Thread
Thread worker = new Thread(new ParameterizedThreadStart(UpdateLoWorker));
worker.Start(dataGridFollow.Rows);
//worker thread
private void UpdateLoWorker(DataRowCollection rows)
{
foreach(DataRow r in rows){
string getID = r.Cells["ID"].Value.ToString();
int ID = int.Parse(getID);
UpdateLo(ID);
}
}
Here you'd have a single non-blocking worker which sequentially handles each ID.
Consider using Asynchronous CTP. It's an asynch pattern Microsoft recently released for download. It should simplify asynch programming tremendouesly. The link is http://msdn.microsoft.com/en-us/vstudio/async.aspx. (Read the whitepaper first)
Your code would look something like the following. (I've not verified my syntax yet, sorry).
private async Task DoTheWork()
{
for(int x = 0; x <= dataGridFollow.Rows.Count - 1; x++)
{
string getID = dataGridFollow.Rows[x].Cells["ID"].Value.ToString();
int ID = int.Parse(getID);
task t = new Task(new Action<object>(UpdateLo), ID);
t.Start();
await t;
}
}
This method returns a Task that can be checked periodically for completion. This follows the pattern of "fire and forget" meaning you just call it and presumably, you don't care when it completes (as long as it does complete before 15 minutes).
EDIT
I corrected the syntax above, you would need to change UpdateLo to take an object instead of an Int.
For a simple background thread runner that will run one thread from a queue at a time you can do something like this:
private List<Thread> mThreads = new List<Thread>();
public static void Main()
{
Thread t = new Thread(ThreadMonitor);
t.IsBackground = true;
t.Start();
}
private static void ThreadMonitor()
{
while (true)
{
foreach (Thread t in mThreads.ToArray())
{
// Runs one thread in the queue and waits for it to finish
t.Start();
mThreads.Remove(t);
t.Join();
}
Thread.Sleep(2000); // Wait before checking for new threads
}
}
// Called from the UI or elsewhere to create any number of new threads to run
public static void DoStuff()
{
Thread t = new Thread(DoCorestuff);
t.IsBackground = true;
mActiveThreads.Add(t);
}
public static void DoStuffCore()
{
// Your code here
}
Problem statement
I have a worker thread that basically scans a folder, going into the files within it, and then sleeps for a while. The scanning operation might take 2-3 seconds but not much more. I'm looking for a way to stop this thread elegantly.
Clarification: I want to stop the thread while it's sleeping, and not while it's scanning. However, the problem is that I do not know what is the current state of the thread. If it's sleeping I want it to exit immediately. If it's scanning, I want it to exit the moment it tries to block.
Attempts at a solution
At first I was using Sleep and Interrupt. Then I found out that Interrupt doesn't really interrupt the Sleep - it only works when the threads TRIES to go into sleeping.
So I switched to Monitor Wait&Pulse. Then I found out that the Pulse only works when I'm actually in the Wait. So now I have a thread which looks like that:
while (m_shouldRun)
{
try
{
DoSomethingThatTakesSeveralSeconds();
lock (this)
{
Monitor.Wait(this, 5000);
}
}
catch (ThreadInterruptedException)
{
m_shouldRun = false;
}
}
And now I need to craft my Stop function. So I started with:
public void Stop()
{
m_shouldRun = false;
lock (this)
{
Monitor.Pulse(this);
}
thread.Join();
}
But this doesn't work because I may be pulsing while the thread works (while it's not waiting). So I added Interrupt:
public void Stop()
{
m_shouldRun = false;
thread.Interrupt();
lock (this)
{
Monitor.Pulse(this);
}
thread.Join();
}
Another option is to use:
public void Stop()
{
m_shouldRun = false;
while (!thread.Join(1000))
{
lock (this)
{
Monitor.Pulse(this);
}
}
}
The question
What is the preferred method? Is there a third method which is preferable?
Another alternative is to use events:
private ManualResetEvent _event = new ManualResetEvent(false);
public void Run()
{
while (true)
{
DoSomethingThatTakesSeveralSeconds();
if (_event.WaitOne(timeout))
break;
}
}
public void Stop()
{
_event.Set();
thread.Join();
}
The way to stop a thread elegantly is to leave it finish by itself. So inside the worker method you could have a boolean variable which will check whether we want to interrupt. By default it will be set to false and when you set it to true from the main thread it will simply stop the scanning operation by breaking from the processing loop.
I recommend to keep it simple:
while (m_shouldRun)
{
DoSomethingThatTakesSeveralSeconds();
for (int i = 0; i < 5; i++) // example: 5 seconds sleep
{
if (!m_shouldRun)
break;
Thread.Sleep(1000);
}
}
public void Stop()
{
m_shouldRun = false;
// maybe thread.Join();
}
This has the following advantages:
It smells like busy waiting, but it's not. $NUMBER_OF_SECONDS checks are done during the waiting phase, which is not comparable to the thousands of checks done in real busy waiting.
It's simple, which greatly reduces the risk of error in multi-threaded code. All your Stop method needs to do is to set m_shouldRun to false and (maybe) call Thread.Join (if it is necessary for the thread to finish before Stop is left). No synchronization primitives are needed (except for marking m_shouldRun as volatile).
I came up with separately scheduling the task:
using System;
using System.Threading;
namespace ProjectEuler
{
class Program
{
//const double cycleIntervalMilliseconds = 10 * 60 * 1000;
const double cycleIntervalMilliseconds = 5 * 1000;
static readonly System.Timers.Timer scanTimer =
new System.Timers.Timer(cycleIntervalMilliseconds);
static bool scanningEnabled = true;
static readonly ManualResetEvent scanFinished =
new ManualResetEvent(true);
static void Main(string[] args)
{
scanTimer.Elapsed +=
new System.Timers.ElapsedEventHandler(scanTimer_Elapsed);
scanTimer.Enabled = true;
Console.ReadLine();
scanningEnabled = false;
scanFinished.WaitOne();
}
static void scanTimer_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)
{
scanFinished.Reset();
scanTimer.Enabled = false;
if (scanningEnabled)
{
try
{
Console.WriteLine("Processing");
Thread.Sleep(5000);
Console.WriteLine("Finished");
}
finally
{
scanTimer.Enabled = scanningEnabled;
scanFinished.Set();
}
}
}
}
}
I have the following code, does this run an endless loop?
I am trying to schedule something every minute and the console application should run continuously until I close it.
class Program
{
static int curMin;
static int lastMinute = DateTime.Now.AddMinutes(-1).Minutes;
static void Main(string[] args)
{
// Not sure about this line if it will run continuously every minute??
System.Threading.Timer timer = new System.Threading.Timer(new TimerCallback(TimCallBack), null, 1000, 60000);
Console.Read();
timer.Dispose();
}
private static void TimCallBack(object o)
{
curMin = DateTime.Now.Minute;
if (lastMinute < curMin)
{
// Do my work every minute
lastMinute = curMin;
}
}
}
KISS - or are you competing for the Rube Goldberg award? ;-)
static void Main(string[] args)
{
while(true)
{
DoSomething();
if(Console.KeyAvailable)
{
break;
}
System.Threading.Thread.Sleep(60000);
}
}
I think your method should work assuming you don't press any keys on the console window. The answer above will definitely work but isn't the prettiest.
As soon as your main() exits, all the other threads will be automatically closed, too.
If it needs to run the whole time, might it be a better solution to create a service? Example here.
Why not add your application to the Windows Task scheduler and do just one "task" per startup of your console app (and don't bother thinking about scheduling yourself?)
And to answer your question: No your sample doesn't "Loop", it's event driven and will close on key press.
Using an event which times out for the stop might work, something like this:
class Program
{
static TimeSpan _timeSpan = new TimeSpan(0, 0, 5);
static ManualResetEvent _stop = new ManualResetEvent(false);
static void Main(string[] args)
{
Console.TreatControlCAsInput = false;
Console.CancelKeyPress += delegate (object sender, ConsoleCancelEventArgs e)
{
_stop.Set();
e.Cancel = true;
};
while (!_stop.WaitOne(_timeSpan))
{
Console.WriteLine("Waiting...");
}
Console.WriteLine("Done.");
}
}