After leaving the scope the thread TimerTest.exe!TimerTest.TimeClass.Callback(object state) is still running.
What is best practise to avoid such running threads?
IDisposable the class TimerClass?
Add a destructor?
Implement a method to dispose the timer?
Small Sample:
using System;
using System.Threading;
namespace TimerTest
{
internal class Program
{
private static void Main(string[] args)
{
// just a scope
{
var timerClass = new TimerClass(1);
}
Console.ReadKey();
}
}
internal class TimerClass
{
private Timer timer;
public TimerClass(int i)
{
this.timer = new Timer(Callback, i, 500, 1000);
}
private void Callback(object state)
{
Console.Out.WriteLine("Timer: " + state);
}
}
}
As you start the timer in the main thread the actually starts a new thread in the threadpool.
If you will implement IDispoable and create the timer class with using like:
(using var timerClass = new TimerClass(1))
{
your code here....
}
In the dispose method you will need to remove refence from the timer so the GC will collect this object as there will be no more refernces to this object.
The best way for my opnion is to use the IDispoe with the using...
You also can clean refenrce from timer in the callback method when you reach the amount of hits.
About the weak refernce - i am not sure that this situation fit to the defintion
Related
I have created a Windows Service that will be calling out to some COM components, so I tagged [STAThread] to the Main function. However, when the timer fires, it reports MTA and the COM calls fail. How can I fix this?
using System;
using System.Diagnostics;
using System.ServiceProcess;
using System.Threading;
using System.Timers;
namespace MyMonitorService
{
public class MyMonitor : ServiceBase
{
#region Members
private System.Timers.Timer timer = new System.Timers.Timer();
#endregion
#region Construction
public MyMonitor ()
{
this.timer.Interval = 10000; // set for 10 seconds
this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed);
}
#endregion
private void timer_Elapsed (object sender, ElapsedEventArgs e)
{
EventLog.WriteEntry("MyMonitor", String.Format("Thread Model: {0}", Thread.CurrentThread.GetApartmentState().ToString()), EventLogEntryType.Information);
}
#region Service Start/Stop
[STAThread]
public static void Main ()
{
ServiceBase.Run(new MyMonitor());
}
protected override void OnStart (string[] args)
{
EventLog.WriteEntry("MyMonitor", "My Monitor Service Started", EventLogEntryType.Information);
this.timer.Enabled = true;
}
protected override void OnStop ()
{
EventLog.WriteEntry("MyMonitor", "My Monitor Service Stopped", EventLogEntryType.Information);
this.timer.Enabled = false;
}
#endregion
}
}
Services are run by the windows service hosting system, which runs using MTA threads. You can't control this. You have to create a new Thread and set its ApartmentState to STA, and do your work on this thread.
Here's a class that extends ServiceBase that does this:
public partial class Service1 : ServiceBase
{
private System.Timers.Timer timer;
public Service1()
{
InitializeComponent();
timer = new System.Timers.Timer();
this.timer.Interval = 10000; // set for 10 seconds
this.timer.Elapsed += new System.Timers.ElapsedEventHandler(Tick);
}
protected override void OnStart(string[] args)
{
timer.Start();
}
private void Tick(object sender, ElapsedEventArgs e)
{
// create a thread, give it the worker, let it go
// is collected when done (not IDisposable)
var thread = new Thread(WorkerMethod);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
OnStop(); // kill the timer
}
private void WorkerMethod(object state)
{
// do your work here in an STA thread
}
protected override void OnStop()
{
timer.Stop();
timer.Dispose();
}
}
Note this code doesn't actually stop the service, it stops the timer. There could be lots of work still being done on multiple threads. For instance, if your work consisted of running multiple queries off a large database you may end up crashing because you have too many threads running at the same time.
In a situation like this, I'd create a set number of STA threads (maybe 2x the number of cores to start off with) which monitor a thread-safe queue for work items. The timer tick event would be responsible for loading that queue with the work needing done.
It all depends on what you're actually doing every ten seconds, whether or not it should be completed the next time the timer ticks, what you should do in this situation, etc etc.
That cannot work in a service, the thread that calls your Main() method was already started by the service manager. You'll need to create a separate thread that is initialized with Thread.SetApartmentState() and pumps a message loop.
Setting the STAThread attribute will not work on a service. It's not being handled the same way as an application, so this will get ignored.
My recommendation would be to manually make a separate thread for your service, set its apartment state, and move everything into it. This way, you can set the thread to STA correctly.
However, there will be another issue here - you'll have to rework the way your service works. You can't just use a System.Threading.Timer instance for timing - it runs on a separate thread, which will not be STA. When its elapsed event fires, you'll be working on a different, non-STA thread.
Instead of doing your work in the timer event, you'll probably want to do your main work in the thread you create explicitly. You can have a reset event in that thread which blocks, and have your timer "set" it to allow your logic to run in the STA thread.
Looking at a similar example: http://www.aspfree.com/c/a/C-Sharp/Creating-a-Windows-Service-with-C-Sharp-introduction/1/
What if your main is...
[STAThread]
public static void Main ()
{
MyMonitor m = new MyMonitor();
m.Start();
}
and move your timer start / stop out of the events...
public void Start() { this.timer.Enabled = true;}
public void Stop() { this.timer.Enabled = false;}
protected override void OnStart (string[] args)
{
EventLog.WriteEntry("MyMonitor", "My Monitor Service Started", EventLogEntryType.Information);
}
protected override void OnStop ()
{
EventLog.WriteEntry("MyMonitor", "My Monitor Service Stopped", EventLogEntryType.Information);
}
This reports that it is using STA. It is based on Will's suggestion and http://en.csharp-online.net/Creating_a_.NET_Windows_Service%E2%80%94Alternative_1:_Use_a_Separate_Thread
using System;
using System.Diagnostics;
using System.ServiceProcess;
using System.Threading;
namespace MyMonitorService
{
internal class MyMonitorThreaded : ServiceBase
{
private Boolean bServiceStarted = false;
private Thread threadWorker;
private void WorkLoop ()
{
while (this.bServiceStarted)
{
EventLog.WriteEntry("MyMonitor", String.Format("Thread Model: {0}", Thread.CurrentThread.GetApartmentState().ToString()), EventLogEntryType.Information);
if (this.bServiceStarted)
Thread.Sleep(new TimeSpan(0, 0, 10));
}
Thread.CurrentThread.Abort();
}
#region Service Start/Stop
protected override void OnStart (String[] args)
{
this.threadWorker = new Thread(WorkLoop);
this.threadWorker.SetApartmentState(ApartmentState.STA);
this.bServiceStarted = true;
this.threadWorker.Start();
}
protected override void OnStop ()
{
this.bServiceStarted = false;
this.threadWorker.Join(new TimeSpan(0, 2, 0));
}
#endregion
}
}
I am trying to create a Windows Service that executes a job on a timer and has graceful shutdown. I've used various questions/answers on here to come up with the code below. It works but I want to make sure it's the most correct and elegant solution. And I have specific questions too (after code).
This is the main service class.
using System;
using System.ServiceProcess;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
namespace MyService
{
public class MyService : ServiceBase
{
CancellationTokenSource cancellationTokenSource;
System.Timers.Timer serviceTimer;
Task workTask;
public static void Main(string[] args)
{
if (!Environment.UserInteractive)
{
Run(new MyService());
}
}
protected override void OnStart(string[] args)
{
cancellationTokenSource = new CancellationTokenSource();
serviceTimer = new System.Timers.Timer(30000);
serviceTimer.Elapsed += new ElapsedEventHandler(serviceTimer_Elapsed);
serviceTimer.Start();
}
protected override void OnStop()
{
try
{
serviceTimer.Stop();
cancellationTokenSource.Cancel();
if (workTask != null)
{
workTask.Wait(10000);
}
}
finally
{
serviceTimer.Dispose();
serviceTimer = null;
cancellationTokenSource.Dispose();
cancellationTokenSource = null;
}
}
private void serviceTimer_Elapsed(object sender, ElapsedEventArgs e)
{
serviceTimer.Stop();
workTask = Task.Run(() => StartWorkMethod()).ContinueWith(WorkCompleted);
}
private void WorkCompleted(Task completedTask)
{
workTask = null;
serviceTimer.Start();
}
private void StartWorkMethod()
{
Work work = new Work(cancellationTokenSource.Token);
work.StartWork();
}
}
}
This is the class that performs the (currently simulated) work.
using System.Threading;
namespace MyService
{
public class Work
{
CancellationToken cancellationToken;
public Work(CancellationToken cancellationToken)
{
this.cancellationToken = cancellationToken;
}
public void StartWork()
{
for (int i = 0; i < 4; i++)
{
if (cancellationToken.IsCancellationRequested)
{
break;
}
Thread.Sleep(10000);
}
}
}
}
The service works and runs all tasks without blocking the handler threads. If the service is stopped, the OnStop method will wait for the task's current block of work to complete for a certain period of time before stopping anyways (thanks Ian of Oz!).
Here are my specific questions:
To prevent the service from stopping immediately and waiting for the current block to complete, I am using the working variable and a while loop to wait for the Work class to complete and the bool to be set to false. Is this the best way to handle this? Already answered by Ian of Oz.
I also want to have a "feature" where if the current block is taking too long to complete, the OnStop method will only wait a certain amount of time before exiting anyways. What is the best way to implement that? Already answerd by Ian of Oz.
I've tried to make sure I handle all threading issues with my code. Is there anything I missed or that might cause trouble later with this implementation?
Also some notes to avoid any confusion:
Service install code is not included, I am using an installer to install the service.
The timer controls the time between executions so that there aren't overlapping executions if the previous execution takes longer; this is why the timer stops before starting the work and restarts after.
I've seen where the Main method is sometimes placed in it's own file, but mostly where the executable is also the installer; in this case it would only simplify this file by the Main method itself.
Edited to incorporate suggestion from Ian of Oz.
Can someone please tell me what is wrong with the following code? Ideally it should start a thread first and then wait for the set event. Instead of that it does not start the thread and just get stuck on WaitOne().
I am curious to know what happened to the thread and why?
class Program
{
static void Main(string[] args)
{
Testing t = Testing.Instance;
Console.Read();
}
}
class Testing
{
private static AutoResetEvent evt = new AutoResetEvent(false);
public static Testing Instance = new Testing();
private Testing()
{
Create();
evt.WaitOne();
Console.WriteLine("out");
}
private void Create()
{
Console.WriteLine("Starting thread");
new Thread(Print).Start();
}
private void Print()
{
Console.WriteLine("started");
evt.Set();
}
}
EDIT:
So far, the description provided by #BrokenGlass makes sense. but changing the code to the following code allows another thread can access the instance methods without constructor being completed.(Suggested by #NicoSchertler).
private static Testing _Instance;
public static Testing Instance
{
get
{
if (_Instance == null)
_Instance = new Testing();
return _Instance;
}
}
I suspect the root cause of this behavior is that the spawned thread cannot access the Print method until the constructor has finished executing - but the constructor never finishes executing because it is waiting on the signal that is triggered only from the Print method.
Replacing the evt.WaitOne() with a long Thread.Sleep() call confirms the same behavior - the constructor must finish running before any instance method of the object may execute from another thread.
The problem is that the second thread is created too early. I'm not sure why, but when started before the main program starts, it will not execute.
You should use the singleton pattern in its original version. This will work.
private static Testing _Instance;
public static Testing Instance
{
get
{
if (_Instance == null)
_Instance = new Testing();
return _Instance;
}
}
Additionally, you should not make the evt variable static. The instance variable should be the only static member of a singleton class in most cases.
My guess would be an issue with the relative timing of the static field initialization. Try initializing evt in the constructor of Testing instead:
private static AutoResetEvent evt;
public static Testing Instance = new Testing();
private Testing()
{
evt = new AutoResetEvent(false);
Create();
evt.WaitOne();
Console.WriteLine("out");
}
I should note this is really just a guess- I'd have thought this code would work fine.
I am a bit new in threading in c# and on general,
in my program I am using mutex to allow only 1 thread getting inside a critical section and for unknown reason with doing some cw prints I can see that more than 1 thread is getting inside my critical section and this is my code :
Mutex m = new Mutex();
m.WaitOne();
<C.S> // critical section here
m.ReleaseMutex();
I would very much like to know if I am doing a mistake here thanks in advance for your kind help.
EDIT:
My code include classes so it basically looks more like this:
public class test
{
private mutex m;
public test()
{
m = new mutex();
}
public func()
{
m.WaitOne();
<C.S> // critical section here
m.ReleaseMutex();
}
}
The problem here is that all your callers are using a different mutex; you need the locking object to be shared, usually by making it a field. For example, and switching to a simpler lock metaphor:
private readonly object syncLock = new object();
public void ThreadSafeMethod() {
lock(syncLock) {
/* critical code */
}
}
or using the mutex:
private readonly Mutex m = new Mutex();
public void ThreadSafeMethod() {
m.WaitOne();
try {
/* critical code */
} finally {
m.ReleaseMutex();
}
}
It looks like you give each Thread its own Mutex. That won't work.
And a Mutex is overkill in most situations. You only need:
private static object syncLock = new object(); // just 1 instance
....
lock(syncLock)
{
// critical section
}
This pattern does no locking at all. Every thread creates a new Mutex object and immediately owns the lock for it. Other threads create and use a new Mutex itself.
Consider using a regular lock()!
lock(_lockobject) {
// do inside what needs to be done - executed on a single thread only
}
where _lockobject is a simple private variable in your class:
private object _lockobject;
Edit: thanks to the commenters! Situations exist, where lock(this) can be dangerous. So I removed that.
Mutex use to identify run app instance.
using (Mutex mutex = new Mutex(true, "app name", out createdNew))
{
if (createdNew)//check app is already run
{
KillOthers();
StartApp();
}
else
{
MessageBox.Show("Another instance already running!");
}
}
May i add a correction to the accepted answer?
private readonly Mutex m = new Mutex();
public void ThreadSafeMethod() {
while(!m.WaitOne()){}
try {
/* critical code */
} finally {
m.ReleaseMutex();
}
}
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?