WaitDialog, когда GUI занимает некоторое время
У меня есть приложение, которое может занять много времени, чтобы выполнить некоторые обновления графического интерфейса. Я не могу запустить это в фоновом потоке, потому что длительная обработка связана с обновлением компонентов графического интерфейса, которые могут быть выполнены только в основном потоке.
Поэтому я создал вспомогательный класс, который будет создавать и отображать форму WaitDialog в фоновом потоке до тех пор, пока графический интерфейс не завершит обновление.
Мой вспомогательный класс выглядит так:
public class ProgressWaitDialogHelper : IDisposable
{
private Thread _thread = null;
public void ShowDialog()
{
ThreadStart threadStart = new ThreadStart(ShowDialogAsync);
_thread = new Thread(threadStart);
_thread.SetApartmentState(ApartmentState.STA);
_thread.Start();
}
public void Dispose()
{
if ((_thread != null) &&
(_thread.IsAlive))
{
_thread.Abort();
}
}
private void ShowDialogAsync()
{
ProgressWaitDialog waitDialog = new ProgressWaitDialog();
waitDialog.ShowDialog();
}
}
Код для вызова вспомогательного класса в моем главном окне графического интерфейса выглядит следующим образом:
using (ProgressWaitDialogHelper waitDialog = new ProgressWaitDialogHelper())
{
waitDialog.ShowDialog();
// Do long running GUI task on main thread here.
}
Кажется, это работает нормально и выглядит точно так, как я хочу на GUI. Форма WaitDialog является модальной и блокирует доступ к основной форме графического интерфейса пользователя, пока она не закончит свои обновления. Как только долго выполняемая задача GUI будет выполнена, она выпадет из блока Using и, таким образом, вызовет метод Dispose для вспомогательного класса, который, в свою очередь, вызовет Abort в потоке.
У меня вопрос, есть ли более изящный способ прекратить поток или лучший способ достижения того же поведения?
1 ответ
Я бы предложил выполнить реальную работу над рабочим потоком и показать ваш журнал ожидания в вашем потоке с графическим интерфейсом. Затем вы можете сообщить своему главному потоку, когда работа завершена, и по завершении работы поток может корректно завершиться обычным способом, и вы можете просто завершить диалог ожидания так же, как и любой другой диалог.