Пример #1
0
        ///<summary>Launches a splash screen with a progressbar that will listen specifically for ODEvents with the passed in name.
        ///Returns an ODProgressWindow that has a Close method that should be invoked whenever the progress window should close.
        ///eventName should be set to the name of the ODEvents that this specific progress window should be processing.</summary>
        ///<param name="currentForm">The form to activate once the progress is done. If you cannot possibly pass in a form, it is okay to pass in null.
        ///</param>
        public static ODProgressWindow ShowProgressSplash(string eventName, Form currentForm)
        {
            //Create a splash form with a progress bar on a separate thread to avoid UI lockups
            bool       isFormClosed = false;
            FormSplash FormS        = new FormSplash(eventName);

            FormS.FormClosed += new FormClosedEventHandler((obj, e) => {
                isFormClosed = true;
            });
            ODThread odThread = new ODThread(new ODThread.WorkerDelegate((ODThread o) => {
                //From this point forward, the only way to kill FormSplash is with a DEFCON 1 message via an ODEvent with the corresponding eventName.
                FormS.ShowDialog();
            }));

            odThread.SetApartmentState(ApartmentState.STA);
            odThread.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception e) => { }));            //Do nothing.
            odThread.Name = "ProgressSplashThread_" + eventName;
            odThread.Start(true);
            return(new ODProgressWindow(new Action(() => {
                //For progress threads, there is a race condition where the DEFCON 1 event will not get processed.
                //This is due to the fact that it took the thread longer to instantiate FormProgressStatus than it took the calling method to invoke this action.
                //Since we don't have access to FormProgressStatus within the thread from here, we simply flag odThread's Tag so that it knows to die.
                if (odThread != null)
                {
                    odThread.Tag = true;
                }
                //Send the phrase that closes the window in case it is processing events.
                SplashProgressEvent.Fire(new ODEventArgs(eventName, "DEFCON 1"));
                if (currentForm != null)
                {
                    //When the form closed on the other thread it was sometimes causing the application to go behind other applications. Calling Activate()
                    //brings the application back to the front or causes it to flash in the taskbar.
                    DateTime start = DateTime.Now;
                    while (!isFormClosed && (DateTime.Now - start).TotalSeconds < 1)                   //Wait till the form is closed or for one second
                    {
                        Thread.Sleep(1);
                    }
                    if (!currentForm.IsDisposed)
                    {
                        currentForm.Activate();
                    }
                }
            })));
        }