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;
}
}
CodePudding user response:
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.
CodePudding user response:
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;
});
}
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;
}
}
}
When I test this, everything disposes correctly under a variety of test conditions. See if you can repro.