(no symbols loaded for any call stack frame
-
Thursday, May 18, 2006 1:27 AM
I have created an excel project in visual studio 2005 with VSTO. My project loads a dataset from SQL. When I try to load the project with a dataset of 5200 or more into a list object, it stops responding. Letting me know that I got a call stack error (no symbols loaded for any call stack frame. The source code cannot be displayed. ), with the following message about MDAs and the message that gives me is:
COM context 0x15a638 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.
I am not using any threading in my project; I don’t need to run anything in the background. I am also not too familiar with threading.
Any ideas what is happening? And how to correct it?
I have tried “disable the LoaderLock exception from Debug->Exceptions->Managed Debugging Assistants->LoaderLock (Remove V from Thrown). “ which I read in another post.
I am going to need to be able to load an excel sheet with 20,000 plus records at a time, not everytime.
Answers
-
Thursday, June 08, 2006 9:43 PMAnswerer
Hi,
What is happening is that you are getting a ContextSwitchDeadlock MDA. You can read about it here: http://msdn2.microsoft.com/en-us/library/ms172233.aspx, but what is going on is that the SQL adapter fills the dataset synchronously so if your backend takes longer than a minute to do the fill, the mda is going to fire. You can certainly disable the mda via the debugger, but you might want to address it. What it is telling you is that your application is monopolizing the cpu.
Ultimately, whether you wish to address this depends on your requirements. The issue with monopolizing the cpu on a UI thread is that you are blocking all user input while you do this. This can result in a poor experience for the user. However, depending on when you do this, it might be OK. For example, you are probably filling the dataset on startup; in that case you may not care that the application isn't accepting input while this is happening (though your users might think they are in a hung state). In fact, you may wish this operation to be synchronous so users may not interact with the application until the fill has completed. If that is what you desire just disable the mda in the exceptions dialog. Otherwise, read on.
The root problem is in the SQL adapter itself; it loops through the dataset reading each row without pumping messages. For large datasets, this is not ideal. However, you can work around the problem yourself by calling the table adapter's Fill method asynchronously. To do this, you will want to extract the Fill code into its own method and then create a delegate that you can call asynchronously. Here is an example:
namespace ExcelWorkbook10
{
internal delegate void AsyncFill();
public partial class Sheet1
{
private AsyncFill fill;
private void Sheet1_Startup(object sender, System.EventArgs e)
{
if (this.NeedsFill("northwindDataSet"))
{
// replace synchronous call with async call
fill = new AsyncFill(Fill);
fill.BeginInvoke(FillComplete, null);
}
}
private void Sheet1_Shutdown(object sender, System.EventArgs e)
{
}
private void Fill()
{
this.customersTableAdapter.Fill(this.northwindDataSet.Customers);
}
private void FillComplete(IAsyncResult result)
{
fill.EndInvoke(result);
}
#region VSTO Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InternalStartup()
{
this.Startup += new System.EventHandler(Sheet1_Startup);
this.Shutdown += new System.EventHandler(Sheet1_Shutdown);
}
#endregion
}
}
Sincerely,
Geoff Darst
Microsoft VSTO Team
All Replies
-
Thursday, May 18, 2006 3:58 PMModeratorA couple things, why would a user want to scroll down past 100 items or so in a list box let alone five thousand!
I can't aswer this problem per-se, but I would recommend these ideas, not necessarily together:- Since you are working with WinForm controls, create a standalone winform test application where you can isolate where the problem resides. Is it the control that has a problem or your SQL/Dataset/provider. Once it works there, then bring it over to the VSTO excel solution.
- Re-engineer how the display of this data is being presented to the user, break it up into commonalitites where maybe a tab control has multiple pages with specific data segments pulled from the dataset.
- Design a paging system of extracting data which happens on demand. Only the first 100 records are shown and once the user scroll past that give them the next 100.
- Note this process may be throttled by the Database at 5000 records and that is why you are hitting a wall.
- Since you are working with WinForm controls, create a standalone winform test application where you can isolate where the problem resides. Is it the control that has a problem or your SQL/Dataset/provider. Once it works there, then bring it over to the VSTO excel solution.
-
Monday, May 22, 2006 5:23 PM
Hi
I think OmegaMan has some very good recommendations that might be used to ensure that your entire solution scales well. Of them, the paging method might be a good idea of loading around 100 records at a time. It will be easier to navigate from a users' perspective.
Nonetheless, if you chose to use 5000 rows, could you tell me more about your ListObject solution. Is there something below the ListObject which needs to be shifted to accomodate 5000 rows? Moreover, have you tried, keeping everything else same, to reduce the number of records? Is there something which is unique about the data you are displaying? To me, it looks like an error that some call is being made into ListObject Excel OM across the Interop boundary (that explains the COM context) and not being returned.
Thanks,
Nikhil -
Monday, May 22, 2006 6:00 PM
There is more going on then just looking at the data. There a few reports created off of the information. So it needs to complete loading the listobject with all the data. each row of data is unique.
currentListObject = Globals.ProjectTemplate.List1
currentListObject.AutoSetDataBoundColumnHeaders =
FalsecurrentListObject.SetDataBinding(dsData.Tables(0))
currentListObject.ShowTotals =
False that is the code i use to load the worksheet.there are named-ranges below and excel has shown no sign of moving named ranges at any time, with the named ranges i have on the pages.
-
Wednesday, May 24, 2006 8:38 PM
There does not look to be anything particularly wrong in the code that you have passed. However. what Im concerned about is the name ranges below the ListObject. To isolate the problem, is it possible you can try to remove the name ranges and try with a listobject on a blank worksheet? How about with reduced number of rows, does it work with/without the namedrange.
Let me know if this helps to isolate the thing which causes the error. On the other hand, if this does not work, is it possible for you to pass me the solution you are using and I will try to repro the error? You can mail it to me at nikhilkh.at.microsoft.com
Thanks,
Nikhil -
Monday, June 05, 2006 6:26 PM
Hi
Has your issue been resolved?
Thanks,
Nikhil -
Thursday, June 08, 2006 9:43 PMAnswerer
Hi,
What is happening is that you are getting a ContextSwitchDeadlock MDA. You can read about it here: http://msdn2.microsoft.com/en-us/library/ms172233.aspx, but what is going on is that the SQL adapter fills the dataset synchronously so if your backend takes longer than a minute to do the fill, the mda is going to fire. You can certainly disable the mda via the debugger, but you might want to address it. What it is telling you is that your application is monopolizing the cpu.
Ultimately, whether you wish to address this depends on your requirements. The issue with monopolizing the cpu on a UI thread is that you are blocking all user input while you do this. This can result in a poor experience for the user. However, depending on when you do this, it might be OK. For example, you are probably filling the dataset on startup; in that case you may not care that the application isn't accepting input while this is happening (though your users might think they are in a hung state). In fact, you may wish this operation to be synchronous so users may not interact with the application until the fill has completed. If that is what you desire just disable the mda in the exceptions dialog. Otherwise, read on.
The root problem is in the SQL adapter itself; it loops through the dataset reading each row without pumping messages. For large datasets, this is not ideal. However, you can work around the problem yourself by calling the table adapter's Fill method asynchronously. To do this, you will want to extract the Fill code into its own method and then create a delegate that you can call asynchronously. Here is an example:
namespace ExcelWorkbook10
{
internal delegate void AsyncFill();
public partial class Sheet1
{
private AsyncFill fill;
private void Sheet1_Startup(object sender, System.EventArgs e)
{
if (this.NeedsFill("northwindDataSet"))
{
// replace synchronous call with async call
fill = new AsyncFill(Fill);
fill.BeginInvoke(FillComplete, null);
}
}
private void Sheet1_Shutdown(object sender, System.EventArgs e)
{
}
private void Fill()
{
this.customersTableAdapter.Fill(this.northwindDataSet.Customers);
}
private void FillComplete(IAsyncResult result)
{
fill.EndInvoke(result);
}
#region VSTO Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InternalStartup()
{
this.Startup += new System.EventHandler(Sheet1_Startup);
this.Shutdown += new System.EventHandler(Sheet1_Shutdown);
}
#endregion
}
}
Sincerely,
Geoff Darst
Microsoft VSTO Team
-
Monday, June 12, 2006 10:30 PMSweet! ... So how do we do this in VB?

