Я пытаюсь отобразить некоторую информацию в сетке, запрашиваемой с сервера SQL. Сбор данных может занять около 10 секунд, поэтому я не хочу блокировать поток пользовательского интерфейса.
У меня есть код:
ThreadPool.QueueUserWorkItem(DataUpdateThread, new UpdateParams(year));
private struct UpdateParams
{
internal string year;
internal UpdateParams(string year)
{
this.year = year;
}
}
private void DataUpdateThread(object state)
{
DataTable dTable = new DataTable();
try
{
this.Invoke((MethodInvoker)delegate
{
//stop data editing on the grid
//scrolling marquee for user
marquee.Visible = true;
marquee.Enabled = true;
grdMain.Visible = false;
grdMain.DataSource = null;
});
UpdateParams parameters = (UpdateParams)state;
dTable = GetData(parameters.year);
}
catch (Exception ex)
{
this.Invoke((MethodInvoker)delegate
{
//log error + end user message
});
}
finally
{
this.Invoke((MethodInvoker)delegate
{
grdMain.DataSource = dTable;
grdMainLevel1.RefreshData();
marquee.Visible = false;
marquee.Enabled = false;
grdMain.Visible = true;
});
}
}
Это работает большую часть времени, за исключением того, что закрываемая форма до завершения обновления завершится с ошибкой:
Невозможно вызвать Invoke или BeginInvoke для элемента управления, пока не будет создан дескриптор окна.
Я понимаю, что ошибка будет из-за того, что форма больше не существует, поэтому, когда раздел finally пытается вызвать метод в потоке пользовательского интерфейса, он не может.
Есть ли лучший способ сделать все это? Я думаю, что могу справиться с ошибками вызова, но это выглядит грязно, и я думаю, что, вероятно, пропустил более простой способ.