У меня проблема с формой, которая использует фоновый рабочий поток для извлечения данных и обновления сетки данных.
Вариант использования - это список с индикаторами выполнения, которые показывают, сколько таблиц загружено вбаза данных.
Идет в следующем порядке,
- FormA создает FormB
- Удары FormB фонового работника, который зацикливается для выборки данных и обновления источника данных datagrid.datasource.
Иногда это работает хорошо, но в других случаях FormB.ShowDialog()
возвращается с нулевым ссылочным исключением.Я не могу понять, почему.
Вот код формы вызова:
private void button1_Click(object sender, EventArgs e)
{
using (var f = new FormFactProgress(_dwConnectionString, _sourceConnectionString, _etlConnectionString))
{
f.ShowDialog(); \\ THIS IS WHERE THE NULL REFERENCE EXCEPTION ALWAYS HAPPENS!
labelLoadWarning.Visible = false;
groupBoxLoadFacts.Enabled = false;
buttonLoadFacts.BackColor = Color.FromArgb(128, 255, 128);
buttonLoadFacts.Text = "Loaded";
if (dynamicWarehouseCatalog.FactsLoaded(_dwConnectionString) && dynamicWarehouseCatalog.DimsLoaded(_dwConnectionString))
{
groupBoxSync.Enabled = true;
}
}
}
Дочерняя форма (это второй фоновый работник, который обновляет сетку данных):
private void buttonStart_Click(object sender, EventArgs e)
{
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
if (!backgroundWorker1.IsBusy)
{
backgroundWorker1.RunWorkerAsync();
}
backgroundWorker2.DoWork += new DoWorkEventHandler(backgroundWorker2_DoWork);
if (!backgroundWorker2.IsBusy)
{
backgroundWorker2.RunWorkerAsync();
}
buttonStart.Enabled = false;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
try
{
BackgroundWorker worker = (BackgroundWorker)sender;
sSISDBCatalog.StartFactLoad(_etlConnectionString);
while (isLoading)
{
System.Threading.Thread.Sleep(1000);
if (dynamicWarehouseCatalog.FactsLoaded(_dwConnectionString))
{
if (dynamicWarehouseCatalog.AllFactsLoaded(_dwConnectionString))
{
isLoading = false;
}
}
}
}
catch(Exception ex)
{
MessageBox.Show(
"Progress viewing has failed. The ETL is still running though. Please monitor your data warehouse growth manually. Error: " + ex, "Pregress Visualisation Failed",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
}
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
try
{
Control.CheckForIllegalCrossThreadCalls = false;
BackgroundWorker worker = (BackgroundWorker)sender;
var dw = DwData(_dwConnectionString);
var source = SourceData(_sourceConnectionString);
dataGridView1.DataSource = GetProgress(dw, source);
while (isLoading)
{
System.Threading.Thread.Sleep(1000);
dw = DwData(_dwConnectionString);
dataGridView1.DataSource = GetProgress(dw, source);
dataGridView1.Refresh();
}
MessageBox.Show(
"Your data warehouse facts are loaded!", "Facts Loaded",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
return;
}
catch (Exception ex)
{
MessageBox.Show(
"Progress viewing has failed. The ETL is still running though. Please monitor your data warehouse growth manually. Error: " + ex, "Pregress Visualisation Failed",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
}