I'm feeling so dumb to ask this but..
How can I prevent my app from exiting without blocking the thread?
Currently it is a console application. But it will be a "windows-app"
(right click in VS on the startup project -> app -> output type: (first) windows app - not a store app. This is just to have an "invisible" app without any kind of GUI. So I can't use Console.ReadLine() later)
What I'm currently doing
var app = WebApp.Start<OwinStartup>(url);
Console.ReadLine(); // wait until I press enter
app.Dispose();
I don't want to block my thread like this
while (isRunning)
{
Thread.Sleep(1000);
}
What possibilities do I have to achieve this?
So a disclaimer, I am not familiar with WebApp at all. However, you could use a ManualResetEvent to accomplish what you want.
using (var app = WebApp.Start<OwinStartup>(url))
{
ManualResetEvent stopHandle = new ManualResetEvent(false);//Might need to be true, I always get this mixed up.
//Pass handle to app somehow
stopHandle.WaitOne();
}
So this code creates the app and then creates a ManualResetEvent. This event is then passed to the app and then the thread stops and waits for it to be set. Inside the app you can set it whenever you want, you can read console input, wait for a button on a page to be clicked or whatever.
I am assuming here that the WebApp class handles creating another thread or uses async to handle web requests. Otherwise you would need to run the app on another thread.
If I have understood your question correctly you are looking for something like below.
Dispatcher.Run();
the above piece of code will keep the thread/app active and wait for message on the Dispatcher as long as shutdown has not been requested on that particular Dispatcher.
Not for a console project you need to add reference to WindowsBase
You can then decide to shutdown the application from another thread.
private static void Main(string[] args)
{
var waitThread = new Thread(Dispatcher.Run) {IsBackground = false};
waitThread.Start();
Console.WriteLine("Application is still running");
//to exit application shutdown waitThread here
}
https://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.run(v=vs.110).aspx
A very simplistic approach will be to display a MessageBox with OK button only. This will block the execution until the user has clicked the button or simply pressed "Enter" key. This I think resembles the behavior of the "Console.ReadLine()" provided you don't actually expect any input at this stage.
You can do an asynchronous application wait using the async and await tag. And this is assuming you have .NET 4.5 as your framework.
private static bool hasExitedApp; // flag to be used for exiting
private static void Main(string[] args)
{
Console.WriteLine("Application is running...");
performAsynchronousWait();
Console.WriteLine("Application is still running...");
// do other processes here
}
private async static void performAsynchronousWait()
{
while (!hasExitedApp)
await Task.Delay(100); // Task.Delay uses a timer, so there's no blocking the UI
Console.WriteLine("Has excited the application...");
// do shutdown processes here
}
I used console here to show that the execution of main will still continue, but the method performAsynchronousWait is still executing. You're UI thread will continue but a background process will still happen.
Related
In the past, using Console apps, I've kept Akka.NET actor systems alive like this:
class Program {
static void Main(string[] args) {
using (var actorSystem = ActorSystem.Create("ExampleSystem")) {
var exampleActor = actorSystem.ActorOf(Props.Create(() => new ExampleActor()), name: "Example");
Console.WriteLine("Akka.NET ActorSystem is now running, press any key to shut down");
Console.ReadKey();
actorSystem.Shutdown();
actorSystem.AwaitTermination(timeout: TimeSpan.FromSeconds(5));
}
}
}
Without the Console.ReadKey(), what's the right way to manage the lifetime of an actor system for a WPF application?
(bonus points: I've heard that Shutdown and AwaitTermination are obsolete, but I'm not sure of the new best practice)
Currently, if you wish to shut down an ActorSystem you should use ActorSystem.Terminate(), which returns a Task that completes once the shutdown has finished.
There is also another property on the ActorSystem, WhenTerminated, which looks like it only exists so that you can get access to the termination task if you need it, without telling the system to terminate.
In your example, Console.ReadKey() is used to block and prevent the process from ending, which isn't necessary in a WPF app. You can either just let your wpf application close if you don't care about the state of the system, or terminate and wait for the termination task to complete if you need the system to shutdown cleanly.
I have a console application, in which I have a connection to a third party windows service on a remote server by tcp/ip.
The call Hierarchy likes:
static class Program
{
[MTAThread]
static void Main()
{
MyApplication.Start();
The Start method
public static void Start()
{
lock (SyncVar)
{
ThreadStart ts = new ThreadStart(MainCode);
MainCodeThread = new Thread(ts);
MainCodeThread.IsBackground = false;
MainCodeThread.Start();
The detail of main thread has:
private static void MainCode()
{
try
{
// connect to the remote server, against a windows service
TelephonyServer tServer = new TelephonyServer(sIpaddress, "username", "password");
while (true)
{
Task consumer = Task.Run(() =>
{
if (data != "")
{
ProcessEachChannel(data);
});
Task producer = Task.Run(() =>
{
// blah blah
});
In the method ProcessEachChannel, we have
public bool ProcessEachChannel(string workItem)
{
ChannelResource cr = tServer.GetChannel();
// blah blah
}
Now the application is working well. However if I click the red exit cross of the application or click stop debugging button from Visual Studio, the resources ChannelResource cr is not destroyed at all. I found the fact from the remote server service control dashboard.
I tried some code
System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
process.Exited += new EventHandler(OnExited);
It is not helpful. I heard some tricks to manage the thread by passing parameters to the main thread then set something true or false etc but just no clue.
The program will not exit until all running threads have been stopped.
Replace the while (true) in the thread code with while (!stopThread.WaitOne(10, false)) where stopThread is a WaitHandle like ManualResetEvent.
Then, when the application shuts down, Set the event and wait for the thread to exit.
Also note that some 3rd-party frameworks depend on Dispose being called on their object because they need to manage the lifetime of some separate threads they've spawned. F.e. read VoiceElements document and see how they call Disconnect and Dispose on a ChannelResource they've got from GetChannel(). Please check with the provider when and where you need to release used resources yourself.
If you kill the process, instead of closing it gracefully (and that is what you do when you close the console window or press the stop buttpn in debugger), there's no chance for any cleanup code to run.
you have to implement some exit handler, perhaps catching a ctrl-c press and then return from your threads, so all objects can cleanly dispose themselves.
I have an application which runs on a single thread, but does a lot of things (executing methods in a loop to automate webbrowser app).
I am a beginner, so the code is probably poorly organized, but I need to add a following feature to the program - a STOP button.
What it needs to do is simply send a 'return;' to any method that is or would be executed next, so that the program returns to a ready-and-waiting stage (i.e. I don't loose user provided data, but no other iteration of any loop is carried out etc.).
Any idea?
I tried System.Threading.Thread.CurrentThread.Abort(); but this actually kills the whole application. Any idea for a good generic solution?
Cheers!
Well first of all if you are just using one thread with your application. Then you cant send cancelTokens to your methods. However if you start using Tasks, which are threads then you can provide yourself the ability to use cancelTokens on your methods.
Here is a very simple example I wrote of using a cancelToken in a program that has threads.
class Program
{
static void Main(string[] args)
{
bool cancelToken = false;
Thread t = new Thread(new ThreadStart(() =>
{
while (!cancelToken)
{
Console.WriteLine("Running....");
Thread.Sleep(1000);
}
}));
t.Start();
Console.ReadKey();
cancelToken = true;
t.Join();
}
}
If you have a single-threaded GUI program, then you can't take any user commands while it's processing something. If you do as others have suggested, and dump the processing into a worker thread, then you can send an interrupt signal to that thread to stop it.
I have a console app that runs some on demand reporting in a webapplication. The app starts, runs some housecleaning, starts a (1 second) timer, and blocks on a Console.ReadLine(); statement. (I've been meaning to stuff it into a service instead, but that's for another day)
Right now this has no exception-handling, so if the sql server it polls against goes down or there is a network hiccup, it just crashes. I'm trying to implement a crude exception-handling now. Inside the timer-callback I have stuffed the sql-query inside a trycatch. If it fails, it handles the exception by logging, increasing a failurecounter and resuming the timer. If it fails more than 5 times I want it to exit the app (sort of) gracefully. How can I force-quit a console app that is blocked with a readline statement?
Code in a gist: https://gist.github.com/cwattengard/11171563
I think a more elegant solution is to block with a reset event. The timer callback sets this at some point when it considers that it no longer has work to do.
static readonly ManualResetEvent reset = new ManualResetEvent(false);
static void Main(string[] args)
{
var t = new Timer(TimerCallback, null, -1, 1000);
t.Change(0, 1000);
reset.WaitOne(); // the application will sit here until the timer tells it to continue.
}
private static void TimerCallback(object state)
{
try
{
// do stuff.
}
catch (Exception e)
{
failureCounter++;
if (failureCounter > 5)
{
reset.Set(); // release the reset event and the application will exit,
return;
}
}
}
The best way would be to use some sort of signalling mechanism.
For example you start the main thread, do all your initialization (timer etc) then create a non signaled ManualResetEvent and wait on it to fire. If the callback from the timer decides the application should terminate it signals the ManualResetEvent and the main thread is released, completes, and terminates the program...
As a matter of general approach, you should always use signaling and ""cooperative multi-tasking"" within your application. In the sense you signal other threads\ tasks\ actors\ whatever to do stuff, you shouldn't forcefully kill them...
I think the best way to make my point is to give you these examples:
Console.ReadLine();
Process.WaitForExit();
These functions will pause the application (without freezing the UI).
I need something like this.
In fact, I am writing something like ReadLine() but in windows forms applications.
When you call this method, it should be waited until the user press Enter.
You can create a thread which does a wait on an AutoResetEvent, the UI thread should continue and accept input which signals the event.
Console apps don't have a UI so there's nothing for WaitForExit() to freeze. In a console app the chrome (title bar and window buttons) are handled by the system. In a WinForms app those things aren't painted until you pass the NC_PAINT events to the default handler. If your main message loop is sleeping then your chrome doesn't get painted.
A WinForms app doesn't close automatically so there should be no reason to call something like WaitForExit(). Instead you explicitly tell the app when to close - say when the user presses escape or something.
You can use backGroundWorker which simply checks for cancellation and waits some time using Thread.Sleep(100) for example.
The other way is to create own thread and control all checks and callbacks yourself.
Try this
Task logManager = Task.Factory.StartNew(() => { /* Your code */ }, TaskCreationOptions.LongRunning);
or even
Task screenshotManager;
private void StartScreenshotManager()
{
screenshotManager = Task.Factory.StartNew(() => { ScreenshotManagerJob(); }, TaskCreationOptions.LongRunning);
screenshotManager.ContinueWith((t) => { ScreenshotManagerUpdateUI(); }, TaskScheduler.FromCurrentSynchronizationContext());
}
private void ScreenshotManagerUpdateUI()
{
// ... UI update work here ...
}
private void ScreenshotManagerJob()
{
// your code
}
Most likely, you don't need to halt the execution at all in Windows Forms application.
Windows Forms applications usually require a much more consistent architecture. If you need some code to proceed after the user input, you should not be halting a function execution. In contrast, open a dialog (or provide any other mean for the user to do the required input) and just wait for him to "interact with it". Interaction should raise C# events that will be processed by an logical class instance that knows how to do it and is subscribed to them.