/// <summary> /// Befor the application stops we must perform some tasks. /// 1. Inform each threa we have runned to stop itself and its childs. /// 2. Wait for the end of each one of these threads (through Join()) /// 3. Write Settings in a file so to save user preferences /// 4. Run the GarbageCleanup thread so to delete any pending file /// (even if there should not be any unmanaged file). /// 5. Wait for the en of the GarbageCleanup thread /// Please note that this method must be called by the entity performing /// the request of stopping the applicaiton. This metho IS NOT automatically /// called by the AppExit() method. /// The way we do this in this application is associating this method to a /// delegate in the BackroundForm: the closing of this form corresponds to /// the end of the application. /// </summary> private void BeforeClosing() { foreach (Window w in openedWindow) { App.Current.Dispatcher.Invoke(() => { try { w.Close(); } catch (Exception e) { ; // NOTHING TO DO } }); } // Stops the hello protocol thread (HelloThread) //if (hellothread.Alive) hellothread.StopThread(); // Stop the receiver thread (ServerClass) //if (receiver.Alive) receiver.StopThread(); // Stop the pipe listener thread (PipeDaemon) //if (pipeListener.Alive) pipeListener.StopThread(); // Lets stop all the thread that are managing outgoing jobs foreach (ExecutableThread t in outgoingJobThreads) { //if (t.Alive) t.StopThread(); } // Waits for the end of all these threads receiver.Join(); pipeListener.Join(); hellothread.Join(); foreach (ExecutableThread t in outgoingJobThreads) { t.Join(); } // Write settings to save user preferences SettingsPersistence.writeSettings(); // Run garbage cleanup thread GarbageCleanup gc = new GarbageCleanup(); gc.run(); gc.Join(); // Wait for completion }
//Deny the user the possibility to open two or more instances of the application void AppStartup(object sender, StartupEventArgs e) { // Only a single instance of this process must e executed bool created; // will be true if the mutext will be created and not retrieved // FROM MSDN DOCS: If name is not null and initiallyOwned is true, the calling thread owns the named mutex only if createdNew is true after the call. mutex = new Mutex(true, "_FileShareApp_Mutex", out created); if (!created) // If the mutex was not created, we are not the first thread trying to execute the program { mutex.Close(); // we don't want the system mantins the mutex opened for us MessageBox.Show("File shar è già in esecuzione. Puoi accedervi dalla task bar.", "Avvio di File Share", MessageBoxButton.OK, MessageBoxImage.Information); Environment.Exit(0); } // Read settings from the settings file so to retrieve user preferences SettingsPersistence.readSettings(); if (Settings.Instance.DontShowSetup == false) { ProfileSetupWindow pw = new ProfileSetupWindow(); pw.ShowDialog(); } // Starts the thread responsible of implementing the Neighboor Discovery protocol InitHelloProtocolThread(); reconnectionAttempts = 0; // Starts the thread responsible of listening for new connections InitReceiverThread(); // Starts the thread responsible of managing pipe connections InitPipeDaemonThread(); /* Start the background form which will manage the tray icon * and the notification window */ bf = new BackgroundForm(); bf.BackgroundFormClosing += BeforeClosing; // A FOOLISH (BUT USEFUL) WAY TO DEBUG A MULTI-USER SITUATION //for (int i = 0; i < 20; i++) { // PeersList.Instance.put(new Peer(new Random().Next() + i + "", new Random().Next() + i + "", new Random().Next() + i + "")); //} }