I'm attempting to transform a simple console application so that it may be used as a service using a nested Service class (relevant code below). The intent is to create a service to perform the actions within the Run method more-or-less at a set interval (eventually, ~hourly).
In short, the Service's OnStart calls my own Start method once, which creates a timer. Inside the timer, I'm creating an instance of the Program class, and performing the Run method till it finishes. I believe this is a valid implementation of what I want that doesn't leave resources outstanding.
Part of what the Run method does is build a dictionary of actions it was unable to perform on the file system, and I would like to retain the dictionary in subsequent calls to Run in order to attempt these actions again, if possible. What would be the best implementation to accomplish this? I'm a bit green and not terribly confident I'm doing things correctly, but I'm attempting to get up to speed as quickly as possible, so any assistance is appreciated.
partial class Program{
static object timerLck = new object();
public class Service : ServiceBase{
public Service(){
ServiceName = Program.ServiceName;
}
protected override void OnStart(string[] args){
Program.Start(args);
}
protected override void OnStop(){
Program.Stop();
}
}
static void Main(string[] args){
if (!Environment.UserInteractive)
using (var service = new Service())
ServiceBase.Run(service);
else{
Start(args);
Stop();
}
}
private static void Start(string[] args){
Timer t = new Timer(CallTimer, null, 0, 50000);
Console.ReadKey();
}
private static void Stop(){
//???
}
static void CallTimer(object state){
bool Lock = false;
try{
Lock = Monitor.TryEnter(timerLck);
if (Lock){
Program Prg = new Program()
var task = Task.Run((Func<Task<int>>)Prg.Run);
task.Wait();
}
}
finally{
if (Lock) Monitor.Exit(timerLck);
}
}
//Perform the repeated actions here
private async Task<int> Run()
{
Dictionary<string, Metadata> d = new Dictionary<string, Metadata>();
//...
return 0;
}
}
You can just have Run accept a Dictionary as a parameter and return the populated Dictionary.
private async Task<Dictionary<string, Metadata>> Run(Dictionary<string,
Metadata> previousErrors)
{
Dictionary<string, Metadata> d = new Dictionary<string, Metadata>();
//...
return d;
}
Then set a property PreviousErrors on your Program class to the returned Dictionary.
static void CallTimer(object state){
bool Lock = false;
try{
Lock = Monitor.TryEnter(timerLck);
if (Lock){
Program Prg = new Program()
var task = Task.Run(()=>Run(PreviousErrors));
PreviousErrors = task.Result;
}
}
finally{
if (Lock) Monitor.Exit(timerLck);
}
}
Note, that I'm only addressing your question not the quality of the rest of the code. It could do with improvements that are outside of the scope of your question.
Related
I have a bit of weird problem that is hard to explain. I have singleton class where in the constructor I have to run a task to initialize some components/resources.
I used 2 implementation of singleton from C# in Depth and in one case everything is working fine, in another case - not.
Code is available below with some comments.
The main problem that for some reason task is not started in one case, when I am using static field with initialier and static contructor (class Test2).
I made some other tests and looks like with the implementation 2 task does not start asynchronically, but starts synchronically after waiting time.
Implementation one. everything is working as expected
public sealed class Test1
{
private static Test1 instance = null;
private static readonly object padlock = new object();
private Test1()
{
using (AutoResetEvent startEvent = new AutoResetEvent(false))
{
new Task(() => TaskThread(startEvent)).Start();
if (!startEvent.WaitOne(1000))
{
throw new Exception("ERROR");
}
}
}
public int Result()
{
return 10;
}
private void TaskThread(AutoResetEvent startEvent)
{
//I am initializing some stuff here
startEvent.Set();
}
public static Test1 Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new Test1();
}
return instance;
}
}
}
}
Implementation 2, task is never started, or started after waiting time of an event
public sealed class Test2
{
private static readonly Test2 instance = new Test2();
static Test2()
{
}
private Test2()
{
using (AutoResetEvent startEvent = new AutoResetEvent(false))
{
new Task(() => TaskThread(startEvent)).Start();
//here it fails to wait successfully and throws an
//exception. Time limit is not reached
if (!startEvent.WaitOne(1000))
{
throw new Exception("ERROR");
}
}
}
public int Result()
{
return 20;
}
private void TaskThread(AutoResetEvent startEvent)
{
//I am initializing some stuff here as well
//but in this implementation code is never reached
startEvent.Set();
}
public static Test2 Instance
{
get
{
return instance;
}
}
}
I am curious why is this happening and how to avoid this problems in future. Thanks a lot!
The root cause of such 'strange' behavior is pretty simple - CLR executes static constructor under a lock. That prevents created thread from entering TaskThread() method and setting startEvent to signaled state.
After you face with such a problem and puzzle for several hours why this is happening, you start to understand why many sources advise not to use doubtful constructs like static constructors, global variables, etc.
I create an example about thread,
I know that use lock could avoid thread suspending at critical section, but I have two questions.
1.Why my program get stuck if I use Thread.Sleep?
In this example, I add sleep to two thread.
Because I wish the console output more slowly, so I can easily see if there's anything wrong.
But if I use Thread.Sleep() then this program will get stuck!
2.What situation should I use Thread.Sleep?
Thanks for your kind response, have a nice day.
class MyThreadExample
{
private static int count1 = 0;
private static int count2 = 0;
Thread t1;
Thread t2;
public MyThreadExample() {
t1 = new Thread(new ThreadStart(increment));
t2 = new Thread(new ThreadStart(checkequal));
}
public static void Main() {
MyThreadExample mt = new MyThreadExample();
mt.t1.Start();
mt.t2.Start();
}
void increment()
{
lock (this)
{
while (true)
{
count1++; count2++;
//Thread.Sleep(0); stuck when use Sleep!
}
}
}
void checkequal()
{
lock (this)
{
while (true)
{
if (count1 == count2)
Console.WriteLine("Synchronize");
else
Console.WriteLine("unSynchronize");
// Thread.Sleep(0);
}
}
}
}
Please take a look at these following codes. Never use lock(this), instead use lock(syncObj) because you have better control over it. Lock only the critical section (ex.: only variable) and dont lock the whole while loop. In method Main, add something to wait at the end "Console.Read()", otherwise, your application is dead. This one works with or without Thread.Sleep. In your code above, your thread will enter "Increment" or "Checkequal" and the lock will never release. Thats why, it works only on Increment or Checkequal and never both.
internal class MyThreadExample
{
private static int m_Count1;
private static int m_Count2;
private readonly object m_SyncObj = new object();
private readonly Thread m_T1;
private readonly Thread m_T2;
public MyThreadExample()
{
m_T1 = new Thread(Increment) {IsBackground = true};
m_T2 = new Thread(Checkequal) {IsBackground = true};
}
public static void Main()
{
var mt = new MyThreadExample();
mt.m_T1.Start();
mt.m_T2.Start();
Console.Read();
}
private void Increment()
{
while (true)
{
lock (m_SyncObj)
{
m_Count1++;
m_Count2++;
}
Thread.Sleep(1000); //stuck when use Sleep!
}
}
private void Checkequal()
{
while (true)
{
lock (m_SyncObj)
{
Console.WriteLine(m_Count1 == m_Count2 ? "Synchronize" : "unSynchronize");
}
Thread.Sleep(1000);
}
}
}
Thread is a little bit old style. If you are a beginner of .NET and using .NET 4.5 or above, then use Task. Much better. All new multithreading in .NET are based on Task, like async await:
public static void Main()
{
var mt = new MyThreadExample();
Task.Run(() => { mt.Increment(); });
Task.Run(() => { mt.Checkequal(); });
Console.Read();
}
I'm not really sure where to look with this problem as I'm not particularly familiar with asynchronous programming. I have a loop which invokes a delegate's BeginInvoke method. When the delegate's callback is executed the loop ceases to execute (it shouldn't). I'm guessing that somehow the thread it's running on is being blocked but I really don't know for sure. Here's a simplified version of the code:
public class TestClass
{
private readonly IService service;
private delegate void TestDelegate();
private bool conditionIsMet = true;
public TestClass( IService service )
{
this.service = service;
}
public void PerformTask()
{
while ( conditionIsMet )
{
var testDelegate = new TestDelegate( service.DoSomething );
testDelegate.BeginInvoke( TestCallback, null );
Thread.Sleep( 1 );
}
}
private void TestCallback( IAsyncResult result )
{
var asyncResult = ( AsyncResult ) result;
var testDelegate = ( TestDelegate ) asyncResult.AsyncDelegate;
testDelegate.EndInvoke( asyncResult );
// After exiting this method the loop in PerformTask() ceases to execute.
// Is it being blocked here somehow?
}
}
In practice there is a bit more to the code but the essential components involved are all here so far as I can tell. In the code sample above I've put a comment in there to indicate the last place the code executes (in the VS debugger, anyway).
I assume that I'm making some sort of fundamental error in the way I'm doing the delegate async invocation but I can't find any docs that explain it to me. Any idea why this is happening?
UPDATE
As part of further testing, I tried this without the EndInvoke call (I know, bad idea in practice) but there was no change in behaviour - it still failed to continue executing the loop.
It works ok for me I think. Are you running it in a console application?
You would need to stop that exiting.
class Program
{
static void Main(string[] args)
{
TestClass t = new TestClass(new Service());
t.PerformTask();
Console.ReadKey();
}
}
public class Service : IService
{
public void DoSomething()
{
Console.WriteLine("Doing something");
}
}
public class TestClass
{
private readonly IService service;
private delegate void TestDelegate();
private bool conditionIsMet = true;
public TestClass(IService service)
{
this.service = service;
}
public void PerformTask()
{
while (conditionIsMet)
{
var testDelegate = new TestDelegate(service.DoSomething);
testDelegate.BeginInvoke(TestCallback, null);
Thread.Sleep(1);
}
}
private void TestCallback(IAsyncResult result)
{
var asyncResult = (AsyncResult)result;
var testDelegate = (TestDelegate)asyncResult.AsyncDelegate;
testDelegate.EndInvoke(asyncResult);
// After exiting this method the loop in PerformTask() ceases to execute.
// Is it being blocked here somehow?
}
}
public interface IService
{
void DoSomething();
}
I post my understanding of C# lock as follows, please help me validate whether or not I get it right.
public class TestLock
{
private object threadLock = new object();
...
public void PrintOne()
{
lock (threadLock)
{
// SectionOne
}
}
public void PrintTwo()
{
lock (threadLock)
{
// SectionTwo
}
}
...
}
Case I> Thread1 and Thread2 simultaneously try to call PrintOne.
Since PrintOne is guarded by the instance lock, at any time, only
one thread can exclusively enter the SectionOne.
Is this correct?
Case II> Thread1 and Thread2 simultaneously try to call PrintOne and PrintTwo
respectively (i.e. Thread1 calls PrintOne and Thread2 calls PrintTwo)
Since two print methods are guarded by the same instance lock, at any time,
only one thread can exclusively access either SectionOne or SectionTwo, but NOT both.
Is this correct?
1 and 2 are true only if all your threads use the same instance of the class. If they use different instances, then both cases are false
Sample
public class TestLock
{
private object threadLock = new object();
public void PrintOne()
{
lock (threadLock)
{
Console.WriteLine("One");
var f = File.OpenWrite(#"C:\temp\file.txt"); //same static resource
f.Close();
}
}
public void PrintTwo()
{
lock (threadLock)
{
Console.WriteLine("Two");
var f = File.OpenWrite(#"C:\temp\file.txt"); //same static resource
f.Close();
}
}
}
And testing code
static void Main(string[] args)
{
int caseNumber = 100;
var threads = new Thread[caseNumber];
for (int i = 0; i < caseNumber; i++)
{
var t = new Thread(() =>
{
//create new instance
var testLock = new TestLock();
//for this instance we safe
testLock.PrintOne();
testLock.PrintTwo();
});
t.Start();
//once created more than one thread, we are unsafe
}
}
One of the possible solutions is to add a static keyword to the locking object declaration and methods that use it.
private static object threadLock = new object();
UPDATE
Good point made by konrad.kruczynski
..."thread safety" is also assumed from
context. For example, I could take
your file opening code and also
generate exception with static lock -
just taking another application
domain. And therefore propose that OP
should use system-wide Mutex class or
sth like that. Therefore static case
is just inferred as the instance one.
Case I: Check ✓
Case II: Check ✓
Don't forget that locking is only one way of thread synchronization. For other userfull methods, read: Thread Synchronization
Straight from MSDN sample:
public class TestThreading
{
private System.Object lockThis = new System.Object();
public void Process()
{
lock (lockThis)
{
// Access thread-sensitive resources.
}
}
}
Yes and yes. Cases are correct.
Your understanding is 100% correct. So if, for instance, you wanted to allow entry into the two methods separately you would want to have two locks.
Yes, you're correct in both counts.
here are the basics (more or less)
1) use instance locks for instance data
public class InstanceOnlyClass{
private int callCount;
private object lockObject = new object();
public void CallMe()
{
lock(lockObject)
{
callCount++;
}
}
}
2) use static locks for static data
public class StaticOnlyClass{
private int createdObjects;
private static object staticLockObject = new object();
public StaticOnlyClass()
{
lock(staticLockObject)
{
createdObjects++;
}
}
}
3) if you are protecting static and instance data use separate static and instance locks
public class StaticAndInstanceClass{
private int createdObjects;
private static object staticLockObject = new object();
private int callCount;
private object lockObject = new object();
public StaticAndInstanceClass()
{
lock(staticLockObject)
{
createdObjects++;
}
}
public void CallMe()
{
lock(lockObject)
{
callCount++;
}
}
}
based on this your code is fine if you are accessing instance data but unsafe if you are modifying static data
For a "log information for support" type of function I'd like to enumerate and dump active thread information.
I'm well aware of the fact that race conditions can make this information semi-inaccurate, but I'd like to try to get the best possible result, even if it isn't 100% accurate.
I looked at Process.Threads, but it returns ProcessThread objects, I'd like to have a collection of Thread objects, so that I can log their name, and whether they're background threads or not.
Is there such a collection available, even if it is just a snapshot of the active threads when I call it?
ie.
Thread[] activeThreads = ??
Note, to be clear, I am not asking about Process.Threads, this collection gives me a lot, but not all of what I want. I want to know how much time specific named threads in our application is currently using (which means I will have to look at connecting the two types of objects later, but the names is more important than the CPU time to begin with.)
If you're willing to replace your application's Thread creations with another wrapper class, said wrapper class can track the active and inactive Threads for you. Here's a minimal workable shell of such a wrapper:
namespace ThreadTracker
{
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
public class TrackedThread
{
private static readonly IList<Thread> threadList = new List<Thread>();
private readonly Thread thread;
private readonly ParameterizedThreadStart start1;
private readonly ThreadStart start2;
public TrackedThread(ParameterizedThreadStart start)
{
this.start1 = start;
this.thread = new Thread(this.StartThreadParameterized);
lock (threadList)
{
threadList.Add(this.thread);
}
}
public TrackedThread(ThreadStart start)
{
this.start2 = start;
this.thread = new Thread(this.StartThread);
lock (threadList)
{
threadList.Add(this.thread);
}
}
public TrackedThread(ParameterizedThreadStart start, int maxStackSize)
{
this.start1 = start;
this.thread = new Thread(this.StartThreadParameterized, maxStackSize);
lock (threadList)
{
threadList.Add(this.thread);
}
}
public TrackedThread(ThreadStart start, int maxStackSize)
{
this.start2 = start;
this.thread = new Thread(this.StartThread, maxStackSize);
lock (threadList)
{
threadList.Add(this.thread);
}
}
public static int Count
{
get
{
lock (threadList)
{
return threadList.Count;
}
}
}
public static IEnumerable<Thread> ThreadList
{
get
{
lock (threadList)
{
return new ReadOnlyCollection<Thread>(threadList);
}
}
}
// either: (a) expose the thread object itself via a property or,
// (b) expose the other Thread public methods you need to replicate.
// This example uses (a).
public Thread Thread
{
get
{
return this.thread;
}
}
private void StartThreadParameterized(object obj)
{
try
{
this.start1(obj);
}
finally
{
lock (threadList)
{
threadList.Remove(this.thread);
}
}
}
private void StartThread()
{
try
{
this.start2();
}
finally
{
lock (threadList)
{
threadList.Remove(this.thread);
}
}
}
}
}
and a quick test driver of it (note I do not iterate over the list of threads, merely get the count in the list):
namespace ThreadTracker
{
using System;
using System.Threading;
internal static class Program
{
private static void Main()
{
var thread1 = new TrackedThread(DoNothingForFiveSeconds);
var thread2 = new TrackedThread(DoNothingForTenSeconds);
var thread3 = new TrackedThread(DoNothingForSomeTime);
thread1.Thread.Start();
thread2.Thread.Start();
thread3.Thread.Start(15);
while (TrackedThread.Count > 0)
{
Console.WriteLine(TrackedThread.Count);
}
Console.ReadLine();
}
private static void DoNothingForFiveSeconds()
{
Thread.Sleep(5000);
}
private static void DoNothingForTenSeconds()
{
Thread.Sleep(10000);
}
private static void DoNothingForSomeTime(object seconds)
{
Thread.Sleep(1000 * (int)seconds);
}
}
}
Not sure if you can go such a route, but it will accomplish the goal if you're able to incorporate at an early stage of development.
Is it feasible for you to store thread information in a lookup as you create each thread in your application?
As each thread starts, you can get its ID using AppDomain.GetCurrentThreadId(). Later, you can use this to cross reference with the data returned from Process.Threads.