0

I have a form that I call from another form. I put all the initialization code in the constructor, so nothing is being called from the Form_Load event. I have stepped through the initialization code, which populates 8 ComboBoxes from a DataSet that was already loaded in the original form. No matter what I do, calling Form.Show() or Form.ShowDialog() takes forever - at least 15 seconds, sometimes more. This is unacceptable for the type of operation being performed; users will never be OK with it.

private void ContextMenuItem_Click(object sender, EventArgs e)
    {
        ToolStripItem mui = sender as ToolStripItem;
        frmAddDataFieldMapping frm = null;
        switch(mui.Name) {
            case "muiAddSourceDataFieldMapping":
                frm = new frmAddDataFieldMapping(this, ((NodeInfo)tvwMain.SelectedNode.Tag), DataFieldMappingTypes.Source);
                break;
            case "muiAddDestinationDataFieldMapping":
                frm = new frmAddDataFieldMapping(this, ((NodeInfo)tvwMain.SelectedNode.Tag), DataFieldMappingTypes.Destination);
                break;
        }
        frm.Show();
}
    public frmAddDataFieldMapping(frmMain _frm, frmMain.NodeInfo _ni, frmMain.DataFieldMappingTypes _dfmt)
        {
            InitializeComponent();

            frm = _frm;
            ni = _ni;
            dfmt = _dfmt;

            if(ni.NodeType == frmMain.NodeTypes.DataField)
            {
                PopulateComboBoxes();
                SetupComboBoxFilters();
            }
        }

        private void PopulateComboBoxes()
        {
            int parentSelectedId = 0;
            if(dfmt == frmMain.DataFieldMappingTypes.Source)
            {
                parentSelectedId = PopulateComboBox(cboSourceDataField, new CboInfo(ni.NodeType, frmMain.DataFieldMappingTypes.Source), ni.Id);
                parentSelectedId = PopulateComboBox(cboSourceDataSet, new CboInfo(frmMain.NodeTypes.DataSet,
                    frmMain.DataFieldMappingTypes.Source), parentSelectedId);
                parentSelectedId = PopulateComboBox(cboSourceDataSource, new CboInfo(frmMain.NodeTypes.DataSource, 
                    frmMain.DataFieldMappingTypes.Source), parentSelectedId);
                parentSelectedId = PopulateComboBox(cboSourceDataSourceType, new CboInfo(frmMain.NodeTypes.DataSourceType, 
                    frmMain.DataFieldMappingTypes.Source), parentSelectedId);
                PopulateComboBox(cboDestinationDataField, new CboInfo(frmMain.NodeTypes.DataField, frmMain.DataFieldMappingTypes.Destination));
                PopulateComboBox(cboDestinationDataSet, new CboInfo(frmMain.NodeTypes.DataSet, frmMain.DataFieldMappingTypes.Destination));
                PopulateComboBox(cboDestinationDataSource, new CboInfo(frmMain.NodeTypes.DataSource, frmMain.DataFieldMappingTypes.Destination));
                PopulateComboBox(cboDestinationDataSourceType, new CboInfo(frmMain.NodeTypes.DataSourceType, frmMain.DataFieldMappingTypes.Destination));
            } else
            {
                parentSelectedId = PopulateComboBox(cboDestinationDataField, new CboInfo(ni.NodeType, frmMain.DataFieldMappingTypes.Destination), ni.Id);
                parentSelectedId = PopulateComboBox(cboDestinationDataSet, new CboInfo(frmMain.NodeTypes.DataSet, 
                    frmMain.DataFieldMappingTypes.Destination), parentSelectedId);
                parentSelectedId = PopulateComboBox(cboDestinationDataSource, new CboInfo(frmMain.NodeTypes.DataSource, 
                    frmMain.DataFieldMappingTypes.Destination), parentSelectedId);
                parentSelectedId = PopulateComboBox(cboDestinationDataSourceType, new CboInfo(frmMain.NodeTypes.DataSourceType, 
                    frmMain.DataFieldMappingTypes.Destination), parentSelectedId);
                PopulateComboBox(cboSourceDataField, new CboInfo(frmMain.NodeTypes.DataField, frmMain.DataFieldMappingTypes.Source));
                PopulateComboBox(cboSourceDataSet, new CboInfo(frmMain.NodeTypes.DataSet, frmMain.DataFieldMappingTypes.Source));
                PopulateComboBox(cboSourceDataSource, new CboInfo(frmMain.NodeTypes.DataSource, frmMain.DataFieldMappingTypes.Source));
                PopulateComboBox(cboSourceDataSourceType, new CboInfo(frmMain.NodeTypes.DataSourceType, frmMain.DataFieldMappingTypes.Source));
            }
        }

        private int PopulateComboBox(ComboBox cbo, CboInfo info, int selectedId = 0)
        {
            int parentSelectedId = 0;

            if(selectedId > 0)
            {
                DataRow[] rows = frm.ds.Tables[info.NodeType.ToString()].Select(frmMain.GetIdField(info.NodeType) + " = " + selectedId.ToString());
                parentSelectedId = (int)rows[0][frmMain.GetIdField(frmMain.GetParentNodeType(info.NodeType))];
            }

            cbo.DataSource = new DataView(frm.ds.Tables[info.NodeType.ToString()]);
            cbo.ValueMember = frmMain.GetIdField(info.NodeType);
            cbo.DisplayMember = frmMain.GetNameField(info.NodeType);
            cbo.BindingContext = this.BindingContext;
            cbo.Tag = info;

            if(selectedId > 0)
            {
                cbo.Enabled = false;
                cbo.SelectedValue = selectedId;
            }

            return parentSelectedId;
        }

E_net4
  • 27,810
  • 13
  • 101
  • 139
  • 4
    Well, at 4 or 5 seconds, hit Break-All to see where you are and what it's doing. We would have to see what you are doing in the constructor of that form otherwise. – LarsTech Jun 04 '19 at 19:09
  • You need to show something while loading the data asynchronously, then show your dialog. –  Jun 04 '19 at 19:28
  • But as I said, I've stepped through the code that loads the data and it runs in a completely acceptable timeframe. If I break on the Show() method, that's where all the time is. – Mike Caputo Jun 04 '19 at 19:37
  • 1
    For the purpose of testing, comment out all the code that you have in the form constructor and let the second form display itself without data. Do you have the same lag? If not then the problem is in the data that you load and put on your user interface elements in the second form – Steve Jun 04 '19 at 19:42
  • 2
    You need to profile your code and figure out where the "slowdown" occurs. You can do this by profiling your application. See [What Are Some Good .NET Profilers?](https://stackoverflow.com/q/3927/1260204) and [Any decent C# profilers out there?](https://stackoverflow.com/q/10644/1260204). – Igor Jun 04 '19 at 19:47
  • OK, I commented out the initialization code and the form loads quickly. But if I step through that same code, it also runs quickly. What am I missing? – Mike Caputo Jun 04 '19 at 19:50
  • Difficult to say anything without seeing what are you doing in that constructor and without knowing the "size" of the data that you are handling. Do you have other form events subscribed like Form_Activate, Form_Resize etc? – Steve Jun 04 '19 at 20:03
  • I do not know how else to phrase that **you need to profile your application at run time**. Any decent profiler will show you where exactly the most amount of time is being spent in your application (or resources consumed depending on your settings). Or you can just continue to guess until you find the code responsible, your call. – Igor Jun 04 '19 at 20:14
  • @Steve No other events. Please see the additional code I've posted above for what's going on in the constructor. – Mike Caputo Jun 04 '19 at 20:16
  • @Igor I can't install a code profile right now because I don't have admin rights on my machine. So I'm trying to figure this out without going through the support process for getting one installed. – Mike Caputo Jun 04 '19 at 20:17
  • You can profile your application [using visual studio](https://duckduckgo.com/?q=performance+profile+visual+studio+profile) as well. – Igor Jun 04 '19 at 20:20
  • In _PopulateComboBox_ move the assignment to the DataSource property after the setting for DisplayMember and ValueMember. You are doing the binding two times – Steve Jun 04 '19 at 20:27
  • @Steve thanks, that seemed to help. It opened in about 4 or 5 seconds. Based on what it's doing, I would expect it to open almost instantly, but at least it's better than it was. – Mike Caputo Jun 04 '19 at 20:30
  • Also not sure about that BindingContext assignment is really needed. – Steve Jun 04 '19 at 20:32
  • @Steve Removed, everything still works. Thanks again for your help. – Mike Caputo Jun 04 '19 at 20:56

0 Answers0