How to stop my Thread in a function from a other function? - c#

I need to stop a Thread when my timer is done.
But this all from a other function.
My Timer starts after Pressing Key: L. a Messagebox appears "Timer started" and my Thread starts too.
after 10 seconds, Timer stops with message but my Thread is still running.
What can i do? :/
void StartFunction()
{
Thread AB = new Thread(SEARCHING) { IsBackground = true };
AB.Start();
}
void StopFunction()
{
Thread AB = new Thread(SEARCHING);
AB.Abort();
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.L)
{
StartFunction();
timer1.Start();
MessageBox.Show("Timer 1 started!");
}
}
int time = 0;
private void timer1_Tick(object sender, EventArgs e)
{
time++;
if (time == 10 && timer1.Enabled)
{
StopFunction();
MessageBox.Show("Timer 1 stoped!");
timer1.Stop();
time = 0;
}
}

Idle_Mind is correct on how to accomplish this. Below is a working example using .NET 6.
One important detail is to use Thread.Join(). This will tell your caller to block until the loop is exited and the method returns.
Here I use the command console to key off the switching of the _running flag. You can do the same with a timer or whatever else. Keep in mind that you should probably also implement IDisposable in your class with the thread in it and set _running to false and do the join there as well. That way, you can instantiate the object with using.
namespace Lala
{
class AB : IDisposable
{
private bool _running = false;
private readonly Thread _thread;
public AB() => _thread = new Thread(Method);
private void Method()
{
while (_running)
{
Console.WriteLine("doing stuff");
Thread.Sleep(1000);
}
}
public void StartMethod()
{
_running = true;
_thread.Start();
}
public void StopMethod()
{
_running = false;
_thread.Join();
}
public void Dispose() => StopMethod();
}
public class Program
{
public static void Main()
{
Console.WriteLine("Launching a Thread. Press any key to stop it");
using AB ab = new();
// AB ab = new(); // if using is not appropriate
ab.StartMethod();
while (!Console.KeyAvailable)
Thread.Sleep(10);
// ab.StopMethod();// if using is not appropriate
}
}
}

Using modern methods you would write something like
private async void Form1_KeyDown(object sender, KeyEventArgs e)
{
var cts = new CancellationTokenSource(10000);
var task = Task.Run(() => Search(cts.Token));
try
{
var result = await task;
// handle result
}
catch (OperationCanceledException)
{
// handle cancelled
}
catch (Exception)
{
// handle other exceptions
}
}
public int Search(CancellationToken cancel)
{
while (true)
{
cancel.ThrowIfCancellationRequested();
// Do searching
if (found)
return result;
}
}
This would use thread pool threads instead of dedicated threads, and avoids the need to manually managing a timer. It also makes it easy to handle the result from the operation, if there are any.

Unfortunately, everything posted before didn't work for me or i just had not understand what i have to do.
Iam a C# Novice and I have a hard time understanding technical terms.
But i found a solution to make this possible.
This stops not the Thread but it Stops the while there has a function in a Thread.
First set a bool on top under public partial class:
public partial class Form1 : Form
{
private volatile bool m_StopThread;
then you have to give your while in the function this:
while (!m_StopThread)
this means that your while is still not running until this is set true.
After this is set, you give your Button or Timer a function maybe like this:
if ()
{
m_StopThread = true;
}
If this function is active your Thread will Start, because now its true and not longer false.
at the same way you can stop this again by set this function to false again.
If the solution I'm explaining has already been suggested, I thank you.
And hope it helps others.
But unfortunately I couldn't understand how to proceed now.
Thank you to those who go out of their way to help people like me every day. :)

Related

Start Stop thread from class

I want to start / stop a thread in order not to block the UI using button
public partial class Program_Form : Form
{
readonly BackgroundWorker m_oWorker;
[STAThread]
private void Program_Form_Load(object sender, EventArgs e)
{
// long code here
}
private async void DGW6BtnPrint_Click(object sender, EventArgs e)
{
Work.Printer_ Print = new Work.Printer_();
await Task.Run(() =>
{
Print.Print_File(this, dataGridView6, StatusText, progressBar1,
varriablesStatus);
});
}
public void BTN6PPauza_Click(object sender, EventArgs e)
{
//What i had tried
//_canceller.Dispose();
//_canceller.Cancel();
// varriablesStatus = false;
//thread2.break;
//autoResetEvent.WaitOne();
//thread2.Join();
//_manualResetEvent.Reset();
//thread2.Abort();
//_pauseEvent.Reset();
//varriablesStatus = "Pause";
//Print_Actions();
}
}
Referenced class:
namespace OfficeTools.Work
{
class Printer_
{
public void Print_File(Program_Form callForm, DataGridView DGW,
TextBox Status, ProgressBar Progress, bool varriablesStatus)
{
foreach (DataGridViewRow Row in DGW.Rows)
{
file = DGW.Rows[Row.Index].Cells[4].Value.ToString();
PrintFiles.Print_Word(file);
}
}
}
}
How can I start stop pause resume the thread because nothing worked from what I had tried, I think the problem is from the foreach loop
I never used threads, and I can not find an example similar with mine in order to understand how should I do.
What you are asking implies that you want to use the Thread.Suspend and Thread.Resume methods. Possibly like this:
private volatile Thread _printThread;
private async void DGW6BtnPrint_Click(object sender, EventArgs e)
{
Work.Printer_ Print = new Work.Printer_();
await Task.Run(() =>
{
_printThread = Thread.CurrentThread;
try
{
Print.Print_File(this, dataGridView6, StatusText, progressBar1,
varriablesStatus);
}
finally { _printThread = null; }
});
}
public void BTN6PPauza_Click(object sender, EventArgs e)
{
var printThread = _printThread;
if (printThread != null)
{
if (printThread.ThreadState.HasFlag(ThreadState.Running))
{
printThread.Suspend();
}
else if (printThread.ThreadState.HasFlag(ThreadState.Suspended))
{
printThread.Resume();
}
}
}
The documentation of these two methods includes several cautionary warnings that discourage usage:
Thread.Suspend has been deprecated. Use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources.
Do not use the Suspend and Resume methods to synchronize the activities of threads. You have no way of knowing what code a thread is executing when you suspend it. If you suspend a thread while it holds locks during a security permission evaluation, other threads in the AppDomain might be blocked. If you suspend a thread while it is executing a class constructor, other threads in the AppDomain that attempt to use that class are blocked. Deadlocks can occur very easily.
It's up to you if you want to accept these risks. If you ask me, you shouldn't.
Note: The Suspend and Resume methods are not supported on .NET Core and later platforms. On these platforms they throw a PlatformNotSupportedException exception. You can use them only if you target the .NET Framework platform.
i made this work, i do not know if it is the right way but for the moment it works
public partial class Program_Form : Form
{
readonly BackgroundWorker m_oWorker;
CancellationTokenSource _tokenSource = null;
[STAThread]
private void Program_Form_Load(object sender, EventArgs e)
{
// long code here
}
private async void DGW6BtnPrint_Click(object sender, EventArgs e)
{
_tokenSource = new CancellationTokenSource();
var token = _tokenSource.Token;
Work.Printer_ Print = new Work.Printer_();
await Task.Run(() =>
{
Print.Print_File(this, dataGridView6, StatusText, progressBar1, token);
});
}
public void BTN6PPauza_Click(object sender, EventArgs e)
{
_tokenSource.Cancel();
}
}
Referenced class:
namespace OfficeTools.Work
{
class Printer_
{
public void Print_File(Program_Form callForm, DataGridView DGW, TextBox Status, ProgressBar Progress, CancellationToken Token)
{
foreach (DataGridViewRow Row in DGW.Rows)
{
file = DGW.Rows[Row.Index].Cells[4].Value.ToString();
PrintFiles.Print_Word(file);
if (Token.IsCancellationRequested)
{
try
{
Winword.Quit(ref missing, ref missing, ref missing);
winword = null;
}
catch { }
return;
}
}
}
}
}
Kind regards all

How to Wake up a sleeping thread?

I made a thread at load event like below:
Thread checkAlert = null;
bool isStop = false;
private void frmMain_Load(object sender, EventArgs e)
{
checkAlert = new Thread(CheckAlert);
checkAlert.Start();
}
void CheckAlert()
{
while (!isStop)
{
Thread.Sleep(60000);
//do work here
}
}
Is there any way to resume the checkAlert thread during it's sleep period?( Thread.Sleep(60000);)
I tried using Thread.Interrupt() but it flows a ThreadInterruptedException, how should I handle this exception? or is there any way to resume the thread?
Edited:
I need to wake up the thread before the "sleep" end because when the user wants to quit the program, the program will have to wait for some time before it really quits ( checkAlert is still running) Is there any way to improve this case?
Based on your comments what it looks like is you need to re-design how CheckAlert works so it does not use Sleep's at all. What you should be doing is using a Timer instead.
System.Timers.Timer timer = null;
public FrmMain()
{
InitializeComponent();
timer = new System.Timers.Timer(60000);
timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
//If you want OnTimedEvent to happen on the UI thread instead of a ThreadPool thread, uncomment the following line.
//timer.SynchronizingObject = this;
if(this.components == null)
this.components = new System.ComponentModel.Container();
//This makes it so when the form is disposed the timer will be disposed with it.
this.componets.Add(timer);
}
private void frmMain_Load(object sender, EventArgs e)
{
timer.Start();
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
//It is good practice not to do complicated logic in a event handler
// if we move the logic to its own method it is much easier to test (you are writing unit tests, right? ;) )
CheckAlert();
}
void CheckAlert()
{
//do work here
}
private void frmMain_Close(object sender, EventArgs e)
{
timer.Stop();
}
If you want the thread to exit automatically when your program quits, simply make it a background thread.
checkAlert = new Thread(CheckAlert);
checkAlert.IsBackground = true;
checkAlert.Start();
It looks to me like you're trying to create a thread which handles two types of events: do something and stop running.
Rather than using a shared variable (isStop) and some other technique to interrupt the thread in order to do work, you might want to use threading events (not to be confused high-level UI Event objects) to control your thread.
AutoResetEvent stop = new AutoResetEvent(false);
AutoResetEvent check = new AutoResetEvent(false);
private void CheckAlert() {
WaitHandle[] handles = new WaitHandle[] { stop, check };
for (;;) {
switch (AutoResetEvent.WaitAny(handles)) {
case 0:
return;
case 1:
// do work
break;
}
}
}
Calling check.Set() in your code will trigger the "do work" branch in the thread and stop.Set() will cause the thread to terminate gracefully.
Once your code has called stop.Set() to terminate the thread, it can call the thread's Join() method to wait until the thread terminates.
EDIT
I misunderstood the question. I will leave the code above in case anyone finds it useful.
If all you want to do is have a thread that performs a task once a minute and stop on demand, you can use the following code:
AutoResetEvent stop = new AutoResetEvent(false);
void CheckAlert() {
var time = new TimeSpan(0, 1, 0); // one minute
while (!stop.WaitOne(time)) {
// do work
}
}
private Thread checkThread;
private void frmMain_Load(object sender, EventArgs e) {
checkThread = new Thread(CheckAlert);
checkThread.Start();
}
private void frmMain_Close(object sender, EventArgs e) {
stop.Set(); // signal thread to stop
checkThread.Join(); // wait for thread to terminate
}
You can see an explanation on how to wake a sleeping thread here:
https://msdn.microsoft.com/en-us/library/tttdef8x%28v=vs.100%29.aspx
and this is a complete example (as you can see, Thread.Interrupt is the good choise... however you have to catch it to continue normal thread execution):
public class HVCSensor : HVCDevice, IDisposable
{
private Thread myThread;
private const int execute_timeout = ((10 + 10 + 6 + 3 + 15 + 15 + 1 + 1 + 15 + 10) * 1000);
private bool disposed = false;
private bool paused = false;
public delegate void HVCResultsHandler(HVC_RESULT res);
public event HVCResultsHandler HVCResultsArrived;
private void OnHVCResultsArrived(HVC_RESULT res)
{
if (HVCResultsArrived != null) {
HVCResultsArrived(res);
}
}
public HVCSensor() {
myThread = new Thread(new ThreadStart(this.execute));
}
private void execute(){
while (!disposed) {
if (!paused && this.IsConnected)
{
HVC_RESULT outRes;
byte status;
try
{
this.ExecuteEx(execute_timeout, activeDetections, imageAcquire, out outRes, out status);
OnHVCResultsArrived(outRes);
}
catch (Exception ex) {
}
}
else {
try
{
Thread.Sleep(1000);
}
catch (ThreadInterruptedException e)
{
}
}
}
}
public HVC_EXECUTION_IMAGE imageAcquire
{
get;
set;
}
public HVC_EXECUTION_FLAG activeDetections
{
get;
set;
}
public void startDetection() {
if(myThread.ThreadState==ThreadState.Unstarted)
myThread.Start();
}
public void pauseDetection() {
paused = true;
}
public void resumeDetection() {
paused = false;
if (myThread.ThreadState == ThreadState.WaitSleepJoin)
myThread.Interrupt();
}
// Implement IDisposable.
// Do not make this method virtual.
// A derived class should not be able to override this method.
public void Dispose()
{
disposed = true;
myThread.Interrupt();
}
}

Timer in C# to run once then after X sec run again

I have some code where the timer EventHandler has this
void timer_Tick(object sender, EventArgs e)
{
try
{
timerRescan.Stop();
ScanForIeInstances()
}
catch (Exception ex)
{
log.Warn("Exception 3", ex);
}
finally
{
timerRescan.Start();
}
}
Naturally there is a race condition with an external entity who may want to Stop the timer down....if the timer is in process and using a thread and someone calls timerRescan.Stop, the timer thread will call Start starting the timer back up again. I am trying to replace this code. There are two methods in java I know and I would like to know how to do both in C#
Run a task every 5 seconds where 5 seconds is the distance between tasks firing
Run a task and AFTER it ends+5seconds run the task again
I would like to use #2 and always fire 5 seconds from the END of the last firing of the event. How do I do that and which timer do I use in C# for that?
This then allows me to have a recurring timer, call start once and have no race condition with the stop(I would rather not have to implement synchronization though I know I could do that as a last resort...would rather just keep the code clean like I can in java)
OR IF you know java, what I am simply looking for is the equivalent of
ScheduledExecutorService.scheduleAtFixedRate - start to start
ScheduledExecutorService.scheduleWithFixedDelay - end to start
A quick way to handle this is to have the external entity set a flag, and then check to see whether that flag has been set:
public bool StopRequested {get; set;}
void timer_Tick(object sender, EventArgs e)
{
if (timerRescan != null) timerRescan.Stop();
if (StopRequested) return;
try
{
ScanForIeInstances()
}
catch (Exception ex)
{
log.Warn("Exception 3", ex);
}
finally
{
timerRescan.Start();
}
}
This doesn't solve the problem if the external entity has a handle on the timer, but the timer should probably be private anyway.
If your only concern is that an external source may want to stop the timer, your best bet is to write a wrapper around this timer that checks a semaphore of sorts....
I have not done any testing of this, but you should be able to grasp the general idea.
public class TimerWrapper
{
public event EventHandler Elapsed;
private System.Timers.Timer timer;
private System.Threading.ManualResetEvent stopped;
private object lockObject = new object();
public TimerWrapper(double interval)
{
stopped = new System.Threading.ManualResetEvent(false);
timer = new System.Timers.Timer(interval);
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Start();
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
lock (lockObject)
{
timer.Stop();
try
{
Elapsed(this, new EventArgs());
}
finally
{
if (!stopped.WaitOne(0)) timer.Start();
}
}
}
public void Start()
{
stopped.Reset();
lock (lockObject)
{
timer.Start();
}
}
public void Stop()
{
stopped.Set();
lock (lockObject)
{
timer.Stop();
}
}
}

C# - Thread Abort and System.NullReferenceException

I am doing a practise GUI Oven program using a thread, I am not sure if I should even be doing this because I want to interact with the GUI when the Heating process is ongoing. When I try to abort the thread by click btnStop_Click, it throws the NullReference exception:
System.NullReferenceException: Object reference not set to an instance of an object.
Please advice on how can I gracefully stop the thread. Thanks.
Code:
public partial class Form1 : Form
{
private Thread t;
public Form1()
{
InitializeComponent();
}
// button to begin heating
private void btnStart_Click(object sender, EventArgs e)
{
if ((txtMin.Text) == "" || (txtSec.Text) == "")
{
MessageBox.Show("Please enter duration of heating");
}
else
{
t = new Thread(heatIt);
btnHeat.Enabled = false;
t.Start();
}
}
//stop heating
private void btnStop_Click(object sender, EventArgs e)
{
Heating heat = new Heating();
Form1 l = new Form1();
l.Subscribe(heat);
heat.stopHeat();
btnHeat.Enabled = true;
}
private void heatIt()
{
// heat food Implementation that calls the 'Heating' class
}
public void Subscribe(Heating m)
{
m.heatComplete += SignalHeatCompleted;
m.heatStop += SignalStop;
}
private void SignalHeatCompleted(Heating m, EventArgs e)
{
MessageBox.Show( "Done, please enjoy your food");
return;
}
private void SignalStop(Heating m, EventArgs e)
{
t.Abort();
MessageBox.Show("Heating Terminated");
return;
}
public class Heating
{
public event HeatingCompleted heatComplete; // Heating Completed Event
public event HeatingStop heatStop; // Heating Stop Event
public EventArgs e = null;
public delegate void HeatingCompleted(Heating h, EventArgs e);
public delegate void HeatingStop(Heating s, EventArgs e);
public void startHeat(int temp, int min, int sec)
{
int totalSec;
totalSec = ((min*60) + sec) * 1000;
Thread.Sleep(totalSec);
if (heatComplete != null)
{
heatComplete(this, e);
}
else
{
//Use default signal if there's no subscription to this event
MessageBox.Show("*TING*");
}
return;
}
public void stopHeat()
{
if (heatStop != null)
{
heatStop(this, e);
}
}
}
}
You are creating a new instance of Form1 in your stop click event and so you are talking to a completely different t from the one in your start click.
You also probably want to have a single instance of Heat that you assign in heatIt and then use that reference in your stop click.
Also for background processing you probably want to look at the BackgroundWorker class to do the heavy lifting for you.
Several remarks:
You should never use Thread.Abort to stop background tasks. This is a bad practice, as it forces aborting the background thread regardless of its state. Use a volatile bool flag instead, and check (every once in a while) if its value has changed.
It seems that your Form represents a UI for business logic extracted into a separate class (Heating). In that case, it probably makes sense to have only a single instance per form, and put it in a private field. Right now you are creating a new instance inside your Stop method, which is probably wrong (since I presume you already use it in the heatIt method).
For each Subscribe method, try to keep a habit of adding a Unsubscribe method, which detaches event handlers at some point. This way GC can collect your listeners after they are no longer needed, and you prevent adding the same event handlers several times.
I would expect something like:
private Heating _heating;
private Thread _workerThread;
private volatile bool _stopRequest = false;
void Start_Btn_Pressed(object sender, EventArgs e)
{
// create the private instance
_heating = new Heating();
Subscribe(_heating);
// start the thread
_stopRequest = false;
_workerThread = new Thread(HeatIt);
_workerThread.Start();
}
void Stop_Btn_Pressed(object sender, EventArgs e)
{
// request stop
_stopRequest = true;
// wait until thread is finished
_workerThread.Join();
// unsubscribe
// ** note that a better place for unsubscribing
// might be at the end of the HeatIt method
Unsubscribe(_heating);
}
And, in your background worker method, you will need to have a loop which checks if _stopRequest has been set:
void HeatIt()
{
while (!_stopRequest && !finishedWork)
{
// do work
}
}
Note that you must have a place in your worker method which will check the _stopRequest flag. Otherwise the only way to stop it is to Abort it (like you did), which is not recommended.
Apart from that, you don't need to stop the thread (like you did in your SignalStop method) once the process is finished. When HeatIt method returns (ends), the thread will also end, and there is no need to do this.

Thread.Interrupt to stop long sleep at app shutdown - Is there a better approach

I'm having a small background thread which runs for the applications lifetime - however when the application is shutdown, the thread should exit gracefully.
The problem is that the thread runs some code at an interval of 15 minutes - which means it sleeps ALOT.
Now in order to get it out of sleep, I toss an interrupt at it - my question is however, if there's a better approach to this, since interrupts generate ThreadInterruptedException.
Here's the gist of my code (somewhat pseudo):
public class BackgroundUpdater : IDisposable
{
private Thread myThread;
private const int intervalTime = 900000; // 15 minutes
public void Dispose()
{
myThread.Interrupt();
}
public void Start()
{
myThread = new Thread(ThreadedWork);
myThread.IsBackground = true; // To ensure against app waiting for thread to exit
myThread.Priority = ThreadPriority.BelowNormal;
myThread.Start();
}
private void ThreadedWork()
{
try
{
while (true)
{
Thread.Sleep(900000); // 15 minutes
DoWork();
}
}
catch (ThreadInterruptedException)
{
}
}
}
There's absolutely a better way - either use Monitor.Wait/Pulse instead of Sleep/Interrupt, or use an Auto/ManualResetEvent. (You'd probably want a ManualResetEvent in this case.)
Personally I'm a Wait/Pulse fan, probably due to it being like Java's wait()/notify() mechanism. However, there are definitely times where reset events are more useful.
Your code would look something like this:
private readonly object padlock = new object();
private volatile bool stopping = false;
public void Stop() // Could make this Dispose if you want
{
stopping = true;
lock (padlock)
{
Monitor.Pulse(padlock);
}
}
private void ThreadedWork()
{
while (!stopping)
{
DoWork();
lock (padlock)
{
Monitor.Wait(padlock, TimeSpan.FromMinutes(15));
}
}
}
For more details, see my threading tutorial, in particular the pages on deadlocks, waiting and pulsing, the page on wait handles. Joe Albahari also has a tutorial which covers the same topics and compares them.
I haven't looked in detail yet, but I wouldn't be surprised if Parallel Extensions also had some functionality to make this easier.
You could use an Event to Check if the Process should end like this:
var eventX = new AutoResetEvent(false);
while (true)
{
if(eventX.WaitOne(900000, false))
{
break;
}
DoWork();
}
There is CancellationTokenSource class in .NET 4 and later which simplifies this task a bit.
private readonly CancellationTokenSource cancellationTokenSource =
new CancellationTokenSource();
private void Run()
{
while (!cancellationTokenSource.IsCancellationRequested)
{
DoWork();
cancellationTokenSource.Token.WaitHandle.WaitOne(
TimeSpan.FromMinutes(15));
}
}
public void Stop()
{
cancellationTokenSource.Cancel();
}
Don't forget that CancellationTokenSource is disposable, so make sure you dispose it properly.
One method might be to add a cancel event or delegate that the thread will subscribe to. When the cancel event is invoke, the thread can stop itself.
I absolutely like Jon Skeets answer. However, this might be a bit easier to understand and should also work:
public class BackgroundTask : IDisposable
{
private readonly CancellationTokenSource cancellationTokenSource;
private bool stop;
public BackgroundTask()
{
this.cancellationTokenSource = new CancellationTokenSource();
this.stop = false;
}
public void Stop()
{
this.stop = true;
this.cancellationTokenSource.Cancel();
}
public void Dispose()
{
this.cancellationTokenSource.Dispose();
}
private void ThreadedWork(object state)
{
using (var syncHandle = new ManualResetEventSlim())
{
while (!this.stop)
{
syncHandle.Wait(TimeSpan.FromMinutes(15), this.cancellationTokenSource.Token);
if (!this.cancellationTokenSource.IsCancellationRequested)
{
// DoWork();
}
}
}
}
}
Or, including waiting for the background task to actually have stopped (in this case, Dispose must be invoked by other thread than the one the background thread is running on, and of course this is not perfect code, it requires the worker thread to actually have started):
using System;
using System.Threading;
public class BackgroundTask : IDisposable
{
private readonly ManualResetEventSlim threadedWorkEndSyncHandle;
private readonly CancellationTokenSource cancellationTokenSource;
private bool stop;
public BackgroundTask()
{
this.threadedWorkEndSyncHandle = new ManualResetEventSlim();
this.cancellationTokenSource = new CancellationTokenSource();
this.stop = false;
}
public void Dispose()
{
this.stop = true;
this.cancellationTokenSource.Cancel();
this.threadedWorkEndSyncHandle.Wait();
this.cancellationTokenSource.Dispose();
this.threadedWorkEndSyncHandle.Dispose();
}
private void ThreadedWork(object state)
{
try
{
using (var syncHandle = new ManualResetEventSlim())
{
while (!this.stop)
{
syncHandle.Wait(TimeSpan.FromMinutes(15), this.cancellationTokenSource.Token);
if (!this.cancellationTokenSource.IsCancellationRequested)
{
// DoWork();
}
}
}
}
finally
{
this.threadedWorkEndSyncHandle.Set();
}
}
}
If you see any flaws and disadvantages over Jon Skeets solution i'd like to hear them as i always enjoy learning ;-)
I guess this is slower and uses more memory and should thus not be used in a large scale and short timeframe. Any other?

Categories