Это общая проблема с многопоточностью, когда речь идет о запуске чего-либо в потоке графического интерфейса, и этот симптом затрагивает все типы разработчиков.
Если бы вы создали отдельный поток, в котором отображалось бы диалоговое окно фактического прогресса, и другой поток для выполнения вызова DCOM, это просто повлекло бы за собой перемещение синхронизации ManuaResetEvent между двумя потоками. Преимущество этого заключается в том, что вы не блокируете поток графического интерфейса, поскольку отдельный поток, который создает форму выполнения, будет создавать свою собственную очередь сообщений, а второй поток, используемый для выполнения вызова DCOM, не должен блокировать какой-либо поток графического интерфейса.
Это требует некоторого тщательного изучения, но когда это сделано, это прекрасно видеть в действии:
private ManualResetEvent _event = new ManualResetEvent(false);
...
private void StartTheComProgressCall()
{
_event.Reset();
ThreadPool.QueueUserWorkItem(StartProgressDialog);
ThreadPool.QueueUserWorkItem(StartDCOMCall);
// there's various possibilities to perform here, we could ideally 1) wait on the
// event to complete, 2) run a callback delegate once everything is done
// 3) fire an event once completed
}
private void StartProgressDialog(object state)
{
ProgressDialog dialog = new ProgressDialog();
dialog.Show();
while(!_event.WaitOne(0))
Application.DoEvents();
dialog.Close();
}
private void StartDCOMCall()
{
...
<perform your DCOM routines here>
// once the call is done, remember to trigger that it's complete
// so that blocking threads can continue to do what they need to do
_event.Set();
}
Примечания
Некоторые могут возразить против использования метода Application.DoEvents()
, но считают, что DoEvents
заставляет обрабатывать любые ожидающие сообщения Windows в очереди сообщений текущего вызывающего потока, и поскольку вызов выполняется в другом потоке (который создал диалог прогресса) ), а не поток GUI, не должно быть больше или этических проблем с «запахом кода» при его использовании. Мы должны использовать любые инструменты или технику, которые помогут нам выполнить работу.