DataGridView refresh causes "Not Responding" application (but onlywhen not in Visual Studio)

A

Aegixx

Ok, extremely wierd situation here:

(I'll post the code below, after the explanation)

I've got a Windows application (.NET 3.5) that has a single Form with
a DataGridView embedded. The user presses a button to do a SQL query
(fill a DataSet). Before firing the query, I disable the grid/buttons
and turn on UseWaitCursor. After it completes, I re-enable the grid/
buttons, refresh the dataset, then turn off the UseWaitCursor. If I
execute this from Visual Studio (in Debug or Release, Run Project or
Manually selecting the executable), it works perfectly fine. But, if
I run the executable manually (straight from Explorer/Command line),
the application goes into a "Not Responding" mode and never returns.
If I attach the debugger to the process, the line that it gets stuck
on is the grid.Enabled = true. If I skip that line, it still gets
stuck, but on the BindingSource.ResetBindings(...) call.

I'll post the code below. Can anyone help me with this?

using System;
using System.ComponentModel;
using System.Configuration;
using System.Windows.Forms;

namespace VAInvoicing
{
public partial class formMain : Form
{
private BackgroundWorker bgWorkerGet;
private BackgroundWorker bgWorkerSend;

public formMain()
{
InitializeComponent();

bgWorkerGet = new BackgroundWorker();
bgWorkerSend = new BackgroundWorker();
bgWorkerSend.WorkerReportsProgress = true;

bgWorkerGet.RunWorkerCompleted += new
RunWorkerCompletedEventHandler(bgWorkerGet_RunWorkerCompleted);
bgWorkerGet.DoWork += new DoWorkEventHandler(bgWorkerGet_DoWork);

bgWorkerSend.RunWorkerCompleted += new
RunWorkerCompletedEventHandler(bgWorkerSend_RunWorkerCompleted);
bgWorkerSend.DoWork += new DoWorkEventHandler(bgWorkerSend_DoWork);
bgWorkerSend.ProgressChanged += new
ProgressChangedEventHandler(bgWorkerSend_ProgressChanged);
}

private void formMain_Load(object sender, EventArgs e)
{
dtStart.Value = DateTime.Today.AddMonths(-1);
dtEnd.Value = DateTime.Today;
}

private void buttonGetInvoices_Click(object sender, EventArgs e)
{
this.UseWaitCursor = true;
panelFilter.Enabled = panelActions.Enabled = false;
statusLabel.Text = "Searching for Invoices...";
progressSend.Style = ProgressBarStyle.Marquee;

bgWorkerGet.RunWorkerAsync();
}

private void bgWorkerGet_DoWork(object sender, DoWorkEventArgs e)
{
eqIpaInvoice2TableAdapter.SetCommandTimeout(120);
eqIpaInvoice2TableAdapter.Fill(eqIpaInvoice2._eqIpaInvoice2,
dtStart.Value, dtEnd.Value,
ConfigurationManager.AppSettings["NameFilter"]);
}

private void bgWorkerGet_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
panelFilter.Enabled = panelActions.Enabled = true;
progressSend.Style = ProgressBarStyle.Blocks;
progressSend.Value = 0;

// Refresh the grid and clear selection
//eqIpaInvoice2BindingSource.ResetBindings(false);
gridInvoices.AutoResizeColumns();
gridInvoices.ClearSelection();

this.UseWaitCursor = false;

// Did an exception occur?
if (e.Error != null)
MessageBox.Show(this, e.Error.GetType().Name + "\n" +
e.Error.Message + "\n\n" + e.Error.StackTrace, "Error!",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}

private void buttonSendInvoices_Click(object sender, EventArgs e)
{
this.UseWaitCursor = true;
panelFilter.Enabled = panelActions.Enabled = false;
statusLabel.Text = "Sending " + gridInvoices.SelectedRows.Count + "
Invoice(s)...";
progressSend.Value = 0;

bgWorkerSend.RunWorkerAsync();
}

private void bgWorkerSend_DoWork(object sender, DoWorkEventArgs e)
{
int success = 0;
int failed = 0;

Random r = new Random();
DataGridViewRow[] rows = new
DataGridViewRow[gridInvoices.SelectedRows.Count];
gridInvoices.SelectedRows.CopyTo(rows, 0);
gridInvoices.ClearSelection();

foreach (DataGridViewRow row in rows)
{
// TODO: Do some work here
System.Threading.Thread.Sleep(1000);

// DEBUG -- Random number -- 30% failure rate
if (r.Next(3) != 1)
{
success++;
row.ErrorText = "";
}
else
{
failed++;
row.ErrorText = "[something went wrong]";
}

bgWorkerSend.ReportProgress((int)Math.Ceiling((int)(success +
failed) / (double)rows.Length * 100));
}

e.Result = success;
}

private void bgWorkerSend_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
progressSend.Value = e.ProgressPercentage;
}

private void bgWorkerSend_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
panelFilter.Enabled = panelActions.Enabled = true;
statusLabel.Text = "Sent " + e.Result.ToString() + " Invoice(s)";

// Make sure buttons are in the correct state
gridInvoices_SelectionChanged(this, new EventArgs());

this.UseWaitCursor = false;

// Did an exception occur?
if (e.Error != null)
MessageBox.Show(this, e.Error.GetType().Name + "\n" +
e.Error.Message + "\n\n" + e.Error.StackTrace, "Error!",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}

private void gridInvoices_SelectionChanged(object sender, EventArgs
e)
{
if (!bgWorkerSend.IsBusy) // Make sure we're not working on sending
now
{
// Show the user how many are selected
statusLabel.Text = gridInvoices.SelectedRows.Count + " / " +
gridInvoices.Rows.Count + " Invoice(s) Selected";

// Only enable Send if there are rows selected.
buttonSendInvoices.Enabled = gridInvoices.SelectedRows.Count > 0;

// Set the default button (for pressing ENTER)
if (gridInvoices.SelectedRows.Count > 0)
this.AcceptButton = buttonSendInvoices;
else
this.AcceptButton = buttonGetInvoices;
}
}
}
}

And here is the Call Stack for the "locked up" process, the last line
is the last User Code executed (or well, attempting to be executed)
is: panelFilter.Enabled = panelActions.Enabled = gridInvoices.Enabled
= true;


[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.Control.Update() +
0x72 bytes
System.Windows.Forms.dll!
System.Windows.Forms.Control.OnEnabledChanged(System.EventArgs e =
{System.EventArgs}) + 0xa7 bytes
System.Windows.Forms.dll!
System.Windows.Forms.DataGridView.OnEnabledChanged(System.EventArgs e)
+ 0xb bytes
System.Windows.Forms.dll!
System.Windows.Forms.Control.Enabled.set(bool value) + 0x59 bytes
 
A

Aegixx

I added the symbols for the .NET Framework and stepped down through
the code. The final call made is:

SafeNativeMethods.UpdateWindow(new HandleRef(window,
InternalHandle));

which is the only line of code in the ControlUpdate method shown in
the top of the Call Stack.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top