C# - Close console application when calculations take more time - c#

I wrote app that is doing repeatedly some task every minute. Problem is that sometimes ( inner calculations ( because CPU was busy or because of any reasons) take more than 50 seconds, then I have to close app. "App monitor that is independent application will turn it on again" so that is not a problem. I implemented watchdog which can tell me if time is finished and then shut down my app.
And my question is if I'm doing it correctly. I test this solution for some time and it looks like working ok.
Main program
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace AppTimer
{
class Program
{
public static appScheduler ap = new appScheduler();
static void Main(string[] args)
{
Console.WriteLine("Press ESC to stop");
while (ap.getWatchDogSeconds() < 55)
{
if (Console.KeyAvailable)
{
if (Console.ReadKey(true).Key == ConsoleKey.Escape)
{
break;
}
}
Thread.Sleep(100);
}
Console.WriteLine("Watchdog Fired ....sw finished !!");
Thread.Sleep(2000);
}
/// <summary>
/// Emulation of long calculation process
/// </summary>
public static void doJob()
{
Console.Clear();
Thread.Sleep(5000);
Console.WriteLine("Busy...");
Console.WriteLine("WatchDog Seconds : " + ap.getWatchDogSeconds());
ap.setWatchDogSeconds(40);
Console.WriteLine("Waiting longer than normal...");
Console.WriteLine("WatchDog Seconds : " + ap.getWatchDogSeconds());
Thread.Sleep(5000);
Console.WriteLine("Maybe sth is down !! or too busy");
Console.WriteLine("WatchDog Seconds : " + ap.getWatchDogSeconds());
while (true)
{
Thread.Sleep(200);
}
}
}
}
Below appScheduler class :
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace AppTimer
{
public class appScheduler
{
static readonly object _lockerWD = new object();
static int minutes = 0;
static int seconds = 50;
static int days = 0;
static int hours = 0;
private static Task calculationsTask;
private int watchDogSeconds = 0;
private int maxSecondsForWatchdog = 50;
public appScheduler()
{
startTimer();
startWatchdogTimer();
}
private void ExecuteSeconds()
{
if (seconds == 0)
{
executeRepeatdTask();
}
calculateTime();
showTimerScreen();
}
private void executeRepeatdTask()
{
calculationsTask = Task.Factory.StartNew(() =>
Program.doJob());
}
public void startTimer()
{
var timer = new System.Threading.Timer((e) =>
{
ExecuteSeconds();
}, null, 0, 1000);
}
public void startWatchdogTimer()
{
var timer = new System.Threading.Timer((e) =>
{
ExecuteSecondsWatchDog();
}, null, 0, 1000);
}
private void ExecuteSecondsWatchDog()
{
Trace.WriteLine("Current amount of WD Seconds : " + watchDogSeconds);
increaseWatchDogSeconds();
}
private void showTimerScreen()
{
if ((calculationsTask == null) || (calculationsTask.IsCompleted == true))
{
//making watchdog zero if time is running and we are showing it!!
Console.Clear();
Console.WriteLine("This is software v1.2");
Console.WriteLine(String.Format("Current execution time : {0} days : {1} hours : {2} : minutes : {3} seconds",
days, hours, minutes, seconds));
Console.WriteLine("WatchDog Seconds : " + watchDogSeconds);
setWatchDogSeconds(0);
}
}
private void calculateTime()
{
seconds++;
if (seconds > 59)
{
seconds = 0;
minutes++;
if (minutes > 59)
{
minutes = 0;
hours++;
if (hours > 23)
{
hours = 0;
days++;
}
}
}
}
public int getMinutes()
{
return minutes;
}
public int getWatchDogSeconds()
{
return watchDogSeconds;
}
public void setWatchDogSeconds(int seconds)
{
Monitor.Enter(_lockerWD);
watchDogSeconds = seconds;
Monitor.Exit(_lockerWD);
}
public void increaseWatchDogSeconds()
{
var seconds = getWatchDogSeconds();
setWatchDogSeconds(seconds += 1);
if (seconds > maxSecondsForWatchdog)
{
Trace.WriteLine(string.Format("More than {0} seconds!", maxSecondsForWatchdog)); ;
Environment.Exit(0);
}
}
}
}

I do a great deal of workflow type tasks every day. I have tried to kick off jobs in the past the way you have here. The only time I use Thread.Sleep is to simulate some long running process in a test environment. I would look into using SetTimer. Also using Thread.Sleep in a loop is not going to give you accurate results. Now, that being said, keeping this running is going to be tricky.
Ultimately kicking off jobs on a regular basis is a breeze if you have an SQL server and can set the call up in an SSIS package. Especially if you are are trying to do this in a web application which might just stop running after a period of time. Good Luck

Related

How many threads in the application? How to set the count of semaphore?

The semaphore means to specify the count how many threads can enter into critical region at a time.
The following code set the count is 5.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static Semaphore semaphore = new Semaphore(5, 5);
static void Main(string[] args)
{
Task.Factory.StartNew(() =>
{
for (int i = 1; i <= 15; ++i)
{
PrintSomething(i);
if (i % 5 == 0)
{
Thread.Sleep(2000);
}
}
});
Console.ReadLine();
}
public static void PrintSomething(int number)
{
semaphore.WaitOne();
Console.WriteLine(number);
semaphore.Release();
}
}
}
Which means each time we can have 5 threads running at any time. The printing result verifies the point.
My question is that I don't see so many threads running. Say 15 threads running, each time only can let 5 threads to be coexisting. There are only two threads.
Am I misunderstood something?
You start one additional thread using Task.Factory.StartNew() and that's it. In that thread you are calling the PrintSomething() method sequentially, so your thread output screenshot is correct.
Change your code as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SempahoreTest1
{
class Program
{
static Semaphore semaphore = new Semaphore(5, 5);
static void Main(string[] args)
{
for (int i = 1; i <= 15; ++i)
{
Task.Factory.StartNew((state) =>
{
int number = (int)state;
PrintSomething(number);
if (i % 5 == 0)
{
Thread.Sleep(2000);
}
}, i);
}
Console.ReadLine();
}
public static void PrintSomething(int number)
{
semaphore.WaitOne();
try
{
Console.WriteLine("Thread: {0}, Number: {1}", Thread.CurrentThread.ManagedThreadId, number);
}
finally
{
semaphore.Release();
}
}
}
}
Update:
A better explanation, how a semaphore works, would be:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SempahoreTest1
{
class Program
{
static Semaphore semaphore = new Semaphore(5, 5);
static Random random = new Random();
static void Main(string[] args)
{
Parallel.For(1, 16, PrintSomething);
Console.ReadLine();
}
public static void PrintSomething(int number)
{
semaphore.WaitOne();
try
{
Console.WriteLine("Thread: {0}, Number: {1}, Access granted", Thread.CurrentThread.ManagedThreadId, number);
// sleep to simulate long running method
Thread.Sleep(random.Next(1000, 5000));
}
finally
{
semaphore.Release();
Console.WriteLine("Thread: {0}, Number: {1}, Semaphore released", Thread.CurrentThread.ManagedThreadId, number);
}
}
}
}
The parallel loop calls PrintSomething() from different threads. On every call the semaphore counter is decreased, until it reaches 0. The next call of PrintSomething() blocks on semaphore.WaitOne(), until the first calls semaphore.Release(), that increments the semaphore counter again. And so on...
The first 5 calls are very fast, because the maximum semaphore count (5) is available. Then, due to the different sleep times, the method call outputs show you, how the semaphore works.

Stopwatch and ReadKey don't work properly

I'm working on my multi-threading password cracker, only numbers. It must show how much time has passed to find the password. I used Stopwatch to find it, but in functions Stopwatch doesn't work. Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Threading;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
int psw = 14995399;
Stopwatch time = new Stopwatch();
Thread Thread1 = new Thread(islem1);
Thread Thread2 = new Thread(islem2);
Thread Thread3 = new Thread(islem3);
Thread Thread4 = new Thread(islem4);
time.Start();
Thread1.Start();
Thread2.Start();
Thread3.Start();
Thread4.Start();
Thread.Sleep(1000);
time.Stop();
System.Console.WriteLine("Time elapsed: {0}", time.Elapsed);
Console.ReadKey();
}
static void islem1()
{
for (int i = 00000000; i < 25000000; i++)
{
int psw = 14995399;
if (i == psw)
{
System.Console.WriteLine("Şifre=" + i);
time.Stop();
Console.WriteLine("Time elapsed: {0}", time.Elapsed);
Console.ReadKey();
}
}
}
static void islem2()
{
for (int i = 25000000; i < 50000000; i++)
{
int psw = 14995399;
if (i == psw)
{
System.Console.WriteLine("Şifre=" + i);
time.Stop();
Console.WriteLine("Time elapsed: {0}", time.Elapsed);
Console.ReadKey();
}
}
}
static void islem3()
{
for (int i = 50000000; i < 75000000; i++)
{
int psw = 14995399;
if (i == psw)
{
System.Console.WriteLine("Şifre=" + i);
time.Stop();
Console.WriteLine("Time elapsed: {0}", time.Elapsed);
Console.ReadKey();
}
}
}
static void islem4()
{
for (int i = 75000000; i < 100000000; i++)
{
int psw = 14995399;
if (i == psw)
{
System.Console.WriteLine("Şifre=" + i);
time.Stop();
Console.WriteLine("Time elapsed: {0}", time.Elapsed);
Console.ReadKey();
}
}
}
}
}
It's because your variable
Stopwatch time = new Stopwatch();
declared outside the visibility functions. The scope of visibility the var is your function Main. You can pass Stopwatch as a parameter to your functions:
Thread1.Start(time);
Or declare it as a class field:
class Program
{
private static Stopwatch time = new Stopwatch();
...
}
Note that you have just one Stopwatch instance then if you stop it in one thread it'll stopped in all application and elapsed time will not changed after that.
Then you should delete time.Stop(); from your Main method because it can caused the result in cased when your threads works longet then 1 second.
Also it's no reason to call Thread.Sleep(). Just delete this lines and your code continues work as expected.
Finally you can delete Console.ReadKey() from your thread functions because your main-thread already waits for user input.
The whole solution with configurable threads count can illustrate interesting results for different number of threads. Try the code below which can illustrate work with thread parameters and reduce lines of code:
using System;
using System.Diagnostics;
using System.Threading;
namespace ConsoleApplication4
{
internal class Program
{
private class BruteforceParams
{
public int StartNumber { get; set; }
public int EndNumber { get; set; }
}
private const int password = 14995399;
private static readonly Stopwatch time = new Stopwatch();
private static void Main(string[] args)
{
const int maxPassword = 100000000;
Console.WriteLine("Enter number of threads: ");
var threadsCountString = Console.ReadLine();
var threadsCount = int.Parse(threadsCountString);
var threads = new Thread[threadsCount];
for (int i = 0; i < threadsCount; i++)
{
var thread = new Thread(Bruteforce);
threads[i] = thread;
}
time.Start();
for (int i = 0; i < threadsCount; i++)
{
threads[i].Start(new BruteforceParams { StartNumber = i * maxPassword / threadsCount, EndNumber = (i + 1) * maxPassword / threadsCount });
}
Console.ReadKey();
}
private static void Bruteforce(object param)
{
var bp = (BruteforceParams) param;
for (int i = bp.StartNumber; i < bp.EndNumber; i++)
{
if (i == password)
{
Console.WriteLine("Şifre=" + i);
time.Stop();
Console.WriteLine("Time elapsed: {0}", time.Elapsed);
}
}
}
}
}
How do you think time.Stop(); going to work inside your function body islem1() or any other since you have defined the stopwatch inside Main() function body. You are bound to get compilation error saying time doesn't exist in current context.
static void islem1()
{
.............
time.Stop(); // this line of code
Console.WriteLine("Time elapsed: {0}", time.Elapsed);
Console.ReadKey();
}
}
}
Rather, you can create a separate watch per method and report that
static void islem1()
{
StopWatch time = Stopwatch.StartNew();
time.Stop(); // this line of code
Console.WriteLine("Time elapsed: {0}", time.Elapsed);
Console.ReadKey();
}
It's going to be difficult to extract meaningful timings using a single Stopwatch instance.
You might chose to make your timing measurements using a different pattern that uses a new Stopwatch for each measurement.
void Main()
{
var t1 = new Thread(_ => {
var sw = Stopwatch.StartNew();
DoSomething();
Console.WriteLine("took {0}ms", sw.ElapsedMilliseconds);
});
var t2 = new Thread(_ => {
var sw = Stopwatch.StartNew();
DoSomethingElse();
Console.WriteLine("took {0}ms", sw.ElapsedMilliseconds);
});
t1.Start();
t2.Start();
t1.Join();
t2.Join();
Console.ReadKey();
}
void DoSomething()
{
//do something
}
void DoSomethingElse()
{
//do something
}

Why does the callback/endinvoke happen after all begin invokes called?

What I'm trying to do is queue up a big list of similar tasks. The time it takes each task to complete is small but there are a lot of them. For each item in the list, I create a delegate and call the delegate.BeginInvoke method then I move to creating the next one.
I would expect in the below example that I would get at least one "****** End Invoke ****" to occur BEFORE all of the begin invokes are called. Instead, it looks like the compiler is starting all of my begin invokes before any end invokes are received.
Is this normal behavior? Is there another way I can send off a task/method on another thread and receive it back while continuing to spur up more tasks?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace AsyncResultTesting
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Starting");
for (int i = 0; i < 100; i++)
{
delMeth d = new delMeth(sleepMethod);
Console.WriteLine(string.Format("Calling the begin invoke from thread: {0} for ID: {1}", Thread.CurrentThread.ManagedThreadId.ToString(), i.ToString()));
IAsyncResult ar = d.BeginInvoke(i, callbackMessage, d);
}
Console.ReadLine();
}
private delegate int delMeth(int id);
private static int sleepMethod(int id)
{
Console.WriteLine(Environment.NewLine + String.Format("Thread: {0} is sleeping. Delegate id is {1}", Thread.CurrentThread.ManagedThreadId.ToString(),id.ToString()));
Console.WriteLine(String.Format("Thread Properties IsThreadPoolThread? = {0} isThreadBackground? = {1} ThreadState: = {2}", Thread.CurrentThread.IsThreadPoolThread.ToString(), Thread.CurrentThread.IsBackground.ToString(), Thread.CurrentThread.ThreadState.ToString()));
Console.WriteLine("");
Thread.Sleep(100);
return id;
}
private static void callbackMessage(IAsyncResult ar)
{
delMeth d = (delMeth)ar.AsyncState;
int result = d.EndInvoke(ar);
Console.WriteLine(Environment.NewLine + "************************ END INVOKE *****************************");
Console.WriteLine(String.Format("Delegate was just called back for id: {0}", result.ToString()));
}
}
}
Unfortunately I have to design this using .NET 3.5 so Task Asynchronous Processing is not available to me.
USR is correct. Everything is functioning how I would expect it to. If i sleep for 10 ms then I see EndInvokes come back in the middle of BeginInvokes.
Thanks USR.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace AsyncResultTesting
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Starting");
for (int i = 0; i < 150; i++) {
delMeth d = new delMeth(sleepMethod);
Console.WriteLine(string.Format("Calling the begin invoke from thread: {0} for ID: {1}", Thread.CurrentThread.ManagedThreadId.ToString(), i.ToString()));
IAsyncResult ar = d.BeginInvoke(i, new AsyncCallback(callbackMessage), d);
}
Console.ReadLine();
}
private delegate int delMeth(int id);
private static int sleepMethod(int id)
{
Console.WriteLine(Environment.NewLine + String.Format("Thread: {0} is sleeping. Delegate id is {1}", Thread.CurrentThread.ManagedThreadId.ToString(),id.ToString()));
Console.WriteLine(String.Format("Thread Properties IsThreadPoolThread? = {0} isThreadBackground? = {1} ThreadState: = {2}", Thread.CurrentThread.IsThreadPoolThread.ToString(), Thread.CurrentThread.IsBackground.ToString(), Thread.CurrentThread.ThreadState.ToString()));
Console.WriteLine("");
Thread.Sleep(10);
return id;
}
private static void callbackMessage(IAsyncResult ar)
{
delMeth d = (delMeth)ar.AsyncState;
int result = d.EndInvoke(ar);
Console.WriteLine(Environment.NewLine + "************************ END INVOKE *****************************");
Console.WriteLine(String.Format("Delegate was just called back for id: {0}", result.ToString()));
}
}
}

No benefits from computationally intensive C# Program?

Im trying to see a performance difference between the following two programs (was expecting). But I find no difference. Is this normal? Im running on a Windows Core 2 Duo M/C
Visual Studio 2010 Express Edition
Program 1 (averaged over 100 runs: 824.11 ms):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
namespace MultiThreading
{
class Program
{
public static Stopwatch stopwatch;
static void Main(string[] args)
{
stopwatch = new Stopwatch();
stopwatch.Start();
//Thread t = new Thread(WriteY);
//t.Start();
for (int i = 0; i < 10000; i++)
{
Console.Write("x{0} ", i);
}
WriteY();
Console.WriteLine("Time taken in milliseconds: {0}", stopwatch.ElapsedMilliseconds);
Console.ReadLine();
}
static void WriteY()
{
for (int i = 0; i < 10000; i++)
{
Console.Write("y{0} ", i);
}
//Console.WriteLine("Time taken in milliseconds: {0}", stopwatch.ElapsedMilliseconds);
//Console.ReadLine();
}
Program 2(averaged over 100 runs: 828.11 ms):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
namespace MultiThreading
{
class Program
{
public static Stopwatch stopwatch;
static void Main(string[] args)
{
stopwatch = new Stopwatch();
stopwatch.Start();
Thread t = new Thread(WriteY);
t.Start();
for (int i = 0; i < 10000; i++)
{
Console.Write("x{0} ", i);
}
//WriteY();
Console.WriteLine("Time taken in milliseconds: {0}", stopwatch.ElapsedMilliseconds);
Console.ReadLine();
}
static void WriteY()
{
for (int i = 0; i < 10000; i++)
{
Console.Write("y{0} ", i);
}
//Console.WriteLine("Time taken in milliseconds: {0}", stopwatch.ElapsedMilliseconds);
//Console.ReadLine();
}
}
}
My guess is that both are bound by the speed of Console.Write which presumably needs to lock the resource (the screen) so that only one thread accesses it at a time.
The problem is that your application is IO-bound because you use Console.WriteLine all the time. If you do something which isn't using IO you will see a boost.
And as mentioned in the other answer WriteLine does indeed synchronize: Calling Console.WriteLine from multiple threads

How to loop a Console App

i just need to be able to loop a console app. what i mean by that is:
program start:
display text
get input
do calculation
display result
display text
get input.
REPEAT PROCESS INFINATE NUMBER OF TIMES UNTIL THE USER EXITS THE APPLICATION.
program end.
i hope that made sense. can anyone please explain how i would go about doing this? thank you :)
Console.WriteLine("bla bla - enter xx to exit");
string line;
while((line = Console.ReadLine()) != "xx")
{
string result = DoSomethingWithThis(line);
Console.WriteLine(result);
}
while(true) {
DisplayText();
GetInput();
DoCalculation();
DisplayResult();
DisplayText();
GetInput();
}
The user can stop the program at any point with CTRL-C.
Is this what you meant?
You could wrap the whole body of your Main method in program.cs in a while loop with a condition that will always be satisfied.
E.g (in pseudo-code)
While (true)
{
Body
}
Kindness,
Dan
Use a While loop
bool userWantsToExit = false;
get input
while(!userWantsToExit)
{
do calc;
display results;
display text;
get input;
if (input == "exit")
userWantsToExit = true;
}
program end;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace InputLoop
{
class Program
{
static long PrintFPSEveryXMilliseconds = 5000;
static double LimitFPSTo = 10.0;
static void Main(string[] args)
{
ConsoleKeyInfo Key = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false);
long TotalFrameCount = 0;
long FrameCount = 0;
double LimitFrameTime = 1000.0 / LimitFPSTo;
do
{
Stopwatch FPSTimer = Stopwatch.StartNew();
while (!Console.KeyAvailable)
{
//Start of Tick
Stopwatch SW = Stopwatch.StartNew();
//The Actual Tick
Tick();
//End of Tick
SW.Stop();
++TotalFrameCount;
++FrameCount;
if (FPSTimer.ElapsedMilliseconds > PrintFPSEveryXMilliseconds)
{
FrameCount = PrintFPS(FrameCount, FPSTimer);
}
if (SW.Elapsed.TotalMilliseconds < LimitFrameTime)
{
Thread.Sleep(Convert.ToInt32(LimitFrameTime - SW.Elapsed.TotalMilliseconds));
}
else
{
Thread.Yield();
}
}
//Print out and reset current FPS
FrameCount = PrintFPS(FrameCount, FPSTimer);
//Read input
Key = Console.ReadKey();
//Process input
ProcessInput(Key);
} while (Key.Key != ConsoleKey.Escape);
}
private static long PrintFPS(long FrameCount, Stopwatch FPSTimer)
{
FPSTimer.Stop();
Console.WriteLine("FPS: {0}", FrameCount / FPSTimer.Elapsed.TotalSeconds);
//Reset frame count and timer
FrameCount = 0;
FPSTimer.Reset();
FPSTimer.Start();
return FrameCount;
}
public static void Tick()
{
Console.Write(".");
}
public static void ProcessInput(ConsoleKeyInfo Key)
{
Console.WriteLine("Pressed {0} Key", Key.KeyChar.ToString());
}
}
}
You can just put a loop around whatever you're doing in your program.

Categories