Show a Window while application is closing - c#

I've a very heavy application that takes some time to close itself (it also depends on the pc where it is running.. but this is not the matter right now)
I would like to show a custom window with a message during this closing time, but as soon as i call the "Shutdown" method every window disappears (except made for the MessageBox).
This is the code i'm trying to use to achieve my objective
void MainWindow_Closing(object sender, CancelEventArgs e)
{
Task.Factory.StartNew(() =>
{
var closingWaitTest = "application closing, please wait;
Application.Current.Dispatcher.Invoke(() =>
{
var closingSplash = new ClosingSplashWindow(closingWaitTest);
closingSplash.Show();
});
MessageBox.Show(closingWaitTest);
});
Application.Current.Shutdown();
}
I Added a messageBox just to check, and it actually works. I mean, the MessageBox stays open until the application process is alive (i check that from the windows TaskManager) while my Window is instantly closed.
Hope someone can give some advice about this,
thanks in advance (:
EDIT -
So, the main problem is that as soon as i call the Application.Current.Shutdown my splash window instantly closes, while the application process is still up and running for some time (disposing all my things before calling shutdown actually reduced this time a bit).
The point is that i would like to show a window for the entirety of time that the process is still up; given the fact that a MessageBox behaves exactly like that, my question is:
Is there a way to make my ClosingSplashWindow behave like a MessageBox and stay visible until the application process is really dead?

Since Application.Current.Shutdown(); is going to close the application immediately. Maybe you first have a flag to track that application is being closed, cancel the Closing event and initiate the Resource cleanup followed by Application.Current.Shutdown(); again.
The Application_Closing handler may get fired once again, since you've a flag which says you're about to close you can directly exit the handler and all should be good.

First of all, you want to have a flag which indicates that your application is currently shutting down:
private bool IsShuttingDown { get; set; }
Then you should cancel closing operation, perform some heavy work and shut down your application:
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (!IsShuttingDown)
{
e.Cancel = true;
ShowSplashWindow();
PerformHeavyOperation();
Application.Current.Shutdown();
IsShuttingDown = true;
}
}

In the end I solved the problem creating another application that shows a window while the main application process is still up and running.
I know it is not the best way to do it, but i was not able to do it in any other way..
Thank for the support! :)

Related

Cross thread exception from minimized winform app

I have a FileSystemWatcher that is waiting for files to appear in a folder, which then triggers an insert to an ObservableCollection. When the form is open on the screen the update happens successfully. But when the form is minimized I get a cross-thread exception? I know I can just check for context, but I want to know why this behaviour is happening so I can ensure it doesn't come up again in other places.
I've tried this with a new blank winform app, and it errors 100% of the time whether it is minimised or not, so I'm unsure what I'm doing wrong or how to diagnose the issue. The main app is thousands of lines long, with many custom libraries so I can't post all of it here.
Called by the watcher
private void CheckForFiles(object source, FileSystemEventArgs e)
{
WaitingFiles.Add(e.FullPath);
}
Which triggers this
private async void WaitingFiles_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
CurrentProcessStatusLabel.Text = "Checking download for despatch file";
}
When I minimize the window I run the following code;
Hide();
SysTrayIcon.Visible = true;
Unless a SynchronizingObject is set, events are raised on a background thread, and background threads are not allowed to update the UI. I'm not sure why it works unless the application is minimized, but a good start is to ensure you are using correct synchronization to avoid issues like this.
If you want to update the UI you should either set the SynchronizingObject to one of the controls in your UI, or manually schedule any UI updates to the UI thread.

How to fix while loop crashing program

I'm trying to have serial data sent out continuously while a check button is being pressed in Visual Studio. So far, this is what I've come up with:
private void checkBox1_CheckedChanged_1(object sender, EventArgs e)
{
while (checkBox1.Checked)
{
serialPort1.Write("D");
Task.Delay(100);
if (checkBox1.Checked != true)
{
break;
}
} `
For some reason, whenever I launch the program and check the box, the program
freezes. I can't exit the program or minimize it or anything. It just stops in its tracks.
The user interface in Windows is based on messages. Your while loop runs in the thread where those messages would be handled. While your code runs, no messages are handled. The user interface cannot be redrawn and cannot react to user input.
Better approach: Use a Timer component. The Tick event of the Timer will be executed every n milliseconds according to the Interval property of the Timer. In the Tick event, you can check the Checkbox state and then do something or not depending on whether the checkbox is checked.
This is a good approach if "do something" is a very short activity. For longer activities, you nee a bit more complex setup that is beyond the scope of a SO question unless you provide more details.
You're blocking the UI thread because your event is being handled synchronously. Refer to this answer for some tips on async/await programming: How do I update the GUI from another thread?

Minimize Event ( C# Win 8.1 app)

I'm developing an App for windows 8.1 and i need to execute a method to pause some tasks or play a sound when the app is minimized in the sidebar.
I tried:
Application.Current.Suspending += new SuspendingEventHandler(Method_Name);
private void Method_Name(object sender, object e)
{
Other_Method();
}
But this event takes a few seconds (5~10) to occur after I minimize the app.
What event occurs when the app is dragged to the sidebar? What process sends the event?
Thanks.
Check out this post for the answer. It's WindowSizeChanged and check the value of ApplicationView.Value.
[EDIT]
Apparently for 8.1 things have changed a bit. The ApplicationView stuff is deprecated (that was quick) but this still takes place in SizeChanged for the window. Check out this for more details.
After long searching I found something that is not exactly what i wanted, but it works.
This event occurs everytime that visibility of the page changes (Is started, is maximized or minimized for exemple), then you must do some conditions using the if operator.
Window.Current.VisibilityChanged += new WindowVisibilityChangedEventHandler(One_Method);
private void One_Method(object sender, Windows.UI.Core.VisibilityChangedEventArgs e)
{
if(Some_Condition)
{
//TODO: Code that you want execute.
}
}
I'll keep the answer in open for the case of someone knows something more efficient.

MessageBox.Show() freezes execution : windows form c#

Good day. I have a form and one backgroundworker . In the bw_Dowork event, there are instances when I need to print a message using MessageBox.Show()(i.e YES?NO box). However, whenever I call the messageBox.Show() method, the execution freezes and the form does not allow me to click my selection (i.e either Yes/No). Sometimes, if I want to work, I have to click fast as the message shows. Otherwise it freezes when I give a seconds of gap. Example of an instance where I use MessageBox.Show() is as shown below:
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
if (fileFTP.Exists == false)
{
_busy.WaitOne();
if ((worker.CancellationPending == true))
{
e.Cancel = true;
return;
}
SetText("File Ftp.exe are missing. This file are required to preform update, please contact yout system administrator to retrive Ftp.exe", true);
MessageBox.Show("File Ftp.exe are missing. This file are required to preform update, please contact yout system administrator to retrive Ftp.exe");
goto ExitProgram;
}
}
After I did some research about this online, some suggested the MessageBox is interfering with the interface thread. This makes me trigger the Messages using delegates but all to no avail. I had to remove all the MessageBoxes. Leaving one still freezes my execution when fired. Please any help would be appreciated.
Try to use the main UI thread to show the messagebox:
this.BeginInvoke((Action)(() => MessageBox.Show("Hello")));
(assuming this is a Form)
Btw: "goto"? seriously?

How do I "Hide()" a Modal WPF Window without it closing?

I have a WPF window that is run on a background thread as a sort of "notifier window"... when an event is raised, it displays a message... a user clicks the "Snooze" button and I call this.Visibility = Visibility.Collapsed
The very moment that I hide the window (either by calling this.Hide() or setting the Visibility as mentioned above)... the "ShowDialog()" code releases the window and closes it.
This is absolutely a bug in the WPF code (which I've identified via reflector)... but my question remains. Has anyone been able to come up with a work-around for this issue?
I've tried many things and am now reaching out to ya'll smart people :)
You can't hide a modal dialog. That's like asking, "How do I get to 100mph in reverse?" You don't, you drive the car forwards.
Use Show, not ShowDialog. Alternately you can simply re-ShowDialog when it needs to become visible again.
Timothy's Answer is good. I just needed for my scenerio to add the following
window.Closed += new EventHandler(window_Closed);
window.Show();
System.Windows.Threading.Dispatcher.Run();
and then in the event...
void window_Closed(object sender, EventArgs e)
{
System.Windows.Threading.Dispatcher.ExitAllFrames();
}
I needed to do this because it was hanging on the Run after the form was really closed.
In order to show modal window always use ShowDialog().
Use Close() instead of Hide().
Handle the FormClosing event like that:
private void OnFormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
this.Visible = false;
}
OK, and as quickly as that - my boss (old C++ goofy guy that he is) figured out the answer.
Here was the code inside of my background thread (which is set to STA mode):
// Show dialog - keeps the thread open and shows the window! Yay!!!
new BeamUI.Notifier.NotifierWindow().ShowDialog();
And here is the modification, that strangely enough works perfectly :)
// Show... hmm, that shows the window... but how do I keep this thread open?
new BeamUI.Notifier.NotifierWindow().Show();
// ZOMG - a line of code that JUST keeps the thread (and msgpump) going!!!
System.Windows.Threading.Dispatcher.Run();
And that's it.
This kinda thing makes me hate C++ people though, and makes me want to just say "if you just built it right in the first place I wouldn't have to look for a work-around!" (j/k)

Categories

Resources