Я использую фона рабочего для обработки загрузки файла, чтобы остановить мой ui от замораживания, однако кажется, что RunWorkerCompleted
заканчивается до завершения моего события DoWork
(вызывает ошибки при выходе из диалога). Я что-то делаю неправильно? Мне лучше делать это над заданием?
public static <T> LoadDesign(string xmlPath)
{
PleaseWait pw = new PleaseWait(xmlPath);
pw.ShowDialog();
return pw.design;
}
private PleaseWait(string xmlFile)
{
InitializeComponent();
bw = new BackgroundWorker();
bw.WorkerSupportsCancellation = true;
bw.DoWork += (s, e) =>
{
design = (Cast)DllCall containing XmlSerializer.Deserialize(...,xmlFile);
};
bw.RunWorkerCompleted += (s, e) => {
//Exit please wait dialog
this.Close();
};
if (!bw.IsBusy)
bw.RunWorkerAsync();
}
Я считаю, что проблема может быть связана с тем, что мой фоновый работник вызывает DLL и не ждет ответа. Я попытался добавить проверки, такие как while(design == null)
, безрезультатно..
Edit2 Ошибка NRE по мере того, как проект не был загружен, я могу легко исправить это, но вместо этого вместо этого будет работать поток.
Есть много маленьких ошибок. Учитывая, что мы, вероятно, не смотрим на реальный код и что у нас нет отладчика с окном Call Stack, чтобы увидеть, где он фактически выйдет из строя, любой из них может быть фактором.
Тестирование bw.IsBusy и не запуск рабочего, когда оно истинно, является серьезной ошибкой. Он никогда не может быть занят в коде как отправленный, но если это действительно возможно, чтобы он был правдой, тогда у вас есть неприятная ошибка в коде. Поскольку вы действительно подписали события на занятого рабочего. Теперь обработчик события RunWorkerCompleted будет выполняться дважды.
Использование метода Close() для закрытия диалогового окна неверно. Диалог должен быть закрыт, назначив его свойство DialogResult. Однако не самая грубая ошибка, но тем не менее неправильная.
Там будет раса в коде, рабочий может завершить до появления диалога. Диалоговое окно можно закрыть только при создании собственного окна. Другими словами, IsHandleCreated должен быть правдой. Вы должны заблокировать это, чтобы этого никогда не было. Подпишите диалоговое окно "Загрузить событие", чтобы запустить рабочий.
Слепо предположить, что работник закончит работу и произведет результат. Это не так, если его метод DoWork умер от исключения. Который пойман BackgroundWorker и передан обработчику события RunWorkerCompleted как свойство e.Error. Вы должны проверить это свойство и сделать что-то разумное, если оно не пустое.
Судя по комментариям, я бы предположил, что последняя пуля является причиной. Вы отлаживаете это с помощью Debug + Exceptions, установите флажок "Бросок" для исключений CLR. Отладчик теперь остановится, когда будет выбрано исключение, что позволит вам узнать, что пошло не так.
Возможно, ваш фоновый рабочий на самом деле не займет много времени и не завершится до того, как появится диалог. Я бы предложил сдвинуть инициализацию рабочего фона и запустить код до PleaseWait
Form_Load или Form_Shown
Shown
, так как это событие вызывается при отображении формы. Load
может быть вызвана задолго до Shown
.
(cast) DllCall
слишком много псевдокода.Using to dll
)