0

It just doesn't react at all if I hit the X button. Not even alt+f4 works

at first I read in two excel files, the read out data is used for some calculation. Edit: Could be that it is an interOp problem:

 System.Data.DataTable dt = new System.Data.DataTable();
            try
            {
                xlApp = new Excel.Application();
                Workbook workbook = xlApp.Workbooks.Open(filePath);
                xlBook = workbook;
                dynamic xlSheet = xlBook.Worksheets[sheetName];
                dynamic xlRange = xlSheet.UsedRange;
                DataRow row = null;
                for (int i = 1; i <= xlRange.Rows.Count; i++)
                {
                    if (i != 1)
                        row = dt.NewRow();
                    for (int j = 1; j <= xlRange.Columns.Count; j++)
                    {
                        if (i == 1)
                            dt.Columns.Add(xlRange.Cells[1, j].value);
                        else
                            row[j - 1] = xlRange.Cells[i, j].value;
                    }
                    if (row != null)
                        dt.Rows.Add(row);
                }
                xlApp = null;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                xlBook.Close();
                //xlApp.Quit();
                if (xlApp != null)
                {
                    xlApp.Quit();
                    xlApp = null;


                }

            }

Everytime you hit the add button on the form starts the calculation and adds a row to a grid view.

Edit: I triggered an event to close the app, but it still doesnt work:

private const int WM_CLOSE = 0x0010;
protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_CLOSE)
    {
        var autoValidate = this.AutoValidate;
        this.AutoValidate = AutoValidate.Disable;
        base.WndProc(ref m);
        this.AutoValidate = autoValidate;
    }
    else
        base.WndProc(ref m);
}
     protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);

            if (e.CloseReason == CloseReason.WindowsShutDown) return;

            // Confirm user wants to close
            switch (MessageBox.Show(this, "Are you sure you want to close?", "Closing", MessageBoxButtons.YesNo))
            {
                case DialogResult.No:
                    e.Cancel = true;

                    break;
                default:
                    break;
            }
        }

  • ok, sorry for my newbie mistake. but i really couldn't decide what to leave and what not. And I was absolutely nervous writing this... -> time pressure -> bad english. – Sadique Khan Jul 07 '22 at 20:30
  • Just edited it, no unnecessary code anymore. – Sadique Khan Jul 07 '22 at 20:40
  • ok, but where shall i set a breakpoint? i tried at the dispose override, but there is no reference. – Sadique Khan Jul 07 '22 at 20:56
  • The Designer's code you have posted is not exactly relevant. Did you subscribe to the `FormClosing` event? When you cannot close the Form, can you instead move it, or is it *frozen*? Do you have closed loop (never ending `for` loops, `while(true)` loops etc.). If not, then post the code you have written and what's in `Program.cs`. – Jimi Jul 07 '22 at 21:37
  • You may want to take a look at this post: [Click Event Not Firing - Cannot Change Focus - Cannot Close Form](https://stackoverflow.com/a/33163068/3110834) Or this one: [How to prevent validating from being fired when I click X (Close button) on the form](https://stackoverflow.com/a/48484847/3110834) – Reza Aghaei Jul 07 '22 at 22:53
  • How do you "read in two Excel files"? Are you using `Microsoft.Office.Interop.Excel` to do that by any chance? What you are describing is the kind of thing that happens when Com objects don't get `Quit` and disposed properly. If this is you, see [How do I properly clean up Excel interop objects from an C# application?](https://stackoverflow.com/questions/60154361/how-do-i-properly-clean-up-excel-interop-objects-from-an-c-sharp-application). Hope this helps; so glad you made a post! – IVSoftware Jul 07 '22 at 23:13
  • Thanks for the comments. I just editet my post, could be that it is an inerop problem. i tried the GC collectors and other things, but the problem stays. – Sadique Khan Jul 14 '22 at 20:26

2 Answers2

0

Your application is stuck in a tight loop iterating over all the content of the Excel file and isn't releasing control back to the UI thread so that it can handle events.

At the bottom of your outermost for loop, call Application.DoEvents() to allow the UI to update and respond to form and control events.

Mike Hofer
  • 16,477
  • 11
  • 74
  • 110
0

Based on your last comment that it might indeed be an interop problem, I wanted to post a minimal example of using the Microsoft.Office.Interop.Excel in a way that disposes of it properly. Because this sample intentionally leaves out the System.DataTable aspects of your code, hopefully it will help you isolate the issue.


Initialize the _xlApp member variable

    public MainForm()
    {
        InitializeComponent();
        _xlApp = new Microsoft.Office.Interop.Excel.Application();            
    }
    private readonly Application _xlApp;
    private Workbook _xlBook = null;

Use the Dispose method (this is probably located in the MainForm.Designer.cs file) to quit the Excel app instance.

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (components != null)
            {
                components.Dispose();
            }
            _xlBook?.Close();
            _xlApp.Quit();
        }
        base.Dispose(disposing);
    }

Use the Excel Visible checkbox to Show/Hide the app

    private void checkBoxExcelVisible_CheckedChanged(object sender, EventArgs e)
    {
        Cursor = Cursors.WaitCursor;
        BeginInvoke((MethodInvoker)delegate 
        {
            _xlApp.Visible = checkBoxExcelVisible.Checked; 
            checkBoxWorkbookOpen.Visible = _xlApp.Visible;
            Cursor = Cursors.Default;
        });
    }

Show excel


Use the Workbook Open checkbox to interact with the the workbook cells and copy them to the textbox.

    private void checkBoxWorkbookOpen_CheckedChanged(object sender, EventArgs e)
    {
        if (checkBoxWorkbookOpen.Checked)
        {
            var filePath = System.IO.Path.Combine(
                AppDomain.CurrentDomain.BaseDirectory,
                "Excel",
                "TestCells.xlsx");

            _xlBook = _xlApp.Workbooks.Open(filePath);
            Worksheet xlSheet = _xlBook.Sheets["Sheet1"];
            Range xlRange = xlSheet.Range["A1", "B4"];

            textBox1.Clear();
            for (int i = 1; i <= xlRange.Rows.Count; i++)
            {
                var line = new List<string>();
                for (int j = 1; j <= xlRange.Columns.Count; j++)
                {
                    Range range = xlRange.Cells[i, j];
                    line.Add(range.Value2);
                }
                textBox1.AppendText(string.Join(" | ", line));
                textBox1.AppendText(Environment.NewLine);
            }
        }
        else
        {
            _xlBook?.Close();
            _xlBook = null;
        }
    }
}

interact with workbook

When I test this, everything disposes correctly under a variety of test conditions. See if you can repro.

IVSoftware
  • 5,732
  • 2
  • 12
  • 23