예제 #1
0
        private void AddError(bool canContinue, string errorMsg, object ex, bool terminateTimerEnabled)
        {
            try
            {
                if (!canContinue)
                {
                    SetCanContinue(false);
                }
                if (terminateTimerEnabled)
                {
                    EnableTerminateTimer();
                }

                ErrorInfo ei = new ErrorInfo();
                ei.ErrorMessage  = errorMsg;
                ei.DetailsObject = ex;
                nextErrors.Enqueue(ei);
                nextButton.Text    = FL.AppErrorDialogNext + " (" + nextErrors.Count + ")";
                nextButton.Visible = true;
            }
            catch (Exception ex2)
            {
                FL.Critical(ex2, "FieldLog.Showing AppErrorDialog", false);
                FL.Flush();
                MessageBox.Show(
                    "Error updating the application error dialog. Details should be logged.",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }
예제 #2
0
        /// <summary>
        /// Shows the application error dialog. This is the only method that is called to show or
        /// update an error dialog. If a dialog is already open, the error is added to it.
        /// </summary>
        /// <param name="canContinue">Indicates whether the application can continue.</param>
        /// <param name="errorMsg">The error message to display.</param>
        /// <param name="ex">The <see cref="Exception"/> instance to display as details object.</param>
        /// <param name="terminateTimerEnabled">Indicates whether the termination safety timer has been started.</param>
        public static void ShowError(bool canContinue, string errorMsg, object ex, bool terminateTimerEnabled)
        {
            lock (syncLock)
            {
                try
                {
                    if (currentInstance == null)
                    {
                        currentInstance = new AppErrorDialog();
                        currentInstance.SetCanContinue(canContinue);
                        currentInstance.errorLabel.Text      = errorMsg;
                        currentInstance.grid.SelectedObject  = ex;
                        currentInstance.detailsLabel.Enabled = ex != null;
                        if (terminateTimerEnabled)
                        {
                            currentInstance.EnableTerminateTimer();
                        }

                        // Source: http://stackoverflow.com/a/3992635/143684
                        uiThread      = new Thread(UiThreadStart);
                        uiThread.Name = "FieldLog.AppErrorDialogUIThread";
                        uiThread.SetApartmentState(ApartmentState.STA);
                        uiThread.Start();
                    }
                    else
                    {
                        // Add next error to existing dialog
                        // Wait until the window handle is created
                        int count = 0;
                        while (!currentInstance.IsHandleCreated)
                        {
                            if (count++ > 500)
                            {
                                throw new TimeoutException("Application error dialog was not created in reasonable time.");
                            }
                            Thread.Sleep(10);
                        }
                        currentInstance.Invoke(new AddErrorDelegate(currentInstance.AddError), canContinue, errorMsg, ex, terminateTimerEnabled);
                    }
                }
                catch (Exception ex2)
                {
                    FL.Critical(ex2, "FieldLog.Showing AppErrorDialog", false);
                    FL.Flush();
                    MessageBox.Show(
                        "Error showing the application error dialog. Details should be logged.",
                        "Error",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                }
            }

            // Make sure we won't continue in this thread if it's not possible
            while (!canContinue)
            {
                Thread.Sleep(1000000);
            }

            // Slow down or halt the application as long as there are many pending errors.
            // The error dialog runs in its own thread so it will still respond to user input. :-)
            // (Unless, of course, should an error occur in the error dialog…)
            if (currentInstance != null && currentInstance.GetNextErrorsCount() >= 20)
            {
                Thread.Sleep(1000);
            }
            while (currentInstance != null && currentInstance.GetNextErrorsCount() >= 40)
            {
                Thread.Sleep(1000);
            }
        }