Почему обертка FileUtilities.CopyFile для CopyFileEx взаимодействует с winforms? - PullRequest
2 голосов
/ 06 декабря 2011

Я использую оболочку FileUtilities.CopyFile для CopyFileEx отсюда http://msdn.microsoft.com/en-us/magazine/cc163851.aspx. Я думал, что CopyFileCallbackAction не будет вызван до тех пор, пока файл не будет скопирован (я пытался скопировать большой файл). И поэтому спросил это Как мне заставить CopyFileEx отчитаться, чтобы я мог отменить операцию копирования файла? вопрос. Но теперь я обнаружил, что он действительно вызывается много раз, но по какой-то причине он портит форму, в которой я пытаюсь показать прогресс - форма не обновляется, пока не будет завершена копия. На самом деле, если я попытаюсь запустить его в обработчике событий Shown - форма будет содержать пустые поля, в которых должны находиться кнопки, - пока не будет завершено копирование. Почему это так?

1 Ответ

9 голосов
/ 06 декабря 2011

Вам нужно будет позвонить CopyFileEx из фонового потока.На данный момент вызов CopyFileEx блокирует поток пользовательского интерфейса.Вот почему пользовательский интерфейс не обновляется.

Действие обратного вызова действительно вызывается неоднократно.Это сделано для того, чтобы вы могли сообщать пользователю о ходе выполнения длительной операции с файлом.

Просто чтобы прояснить ситуацию, это то, что происходит при вызове CopyFileEx:

Enter CopyFileEx
  Start copying
  Call your callback
  Continue copying
  Call your callback
  ....
Return from CopyFileEx

В течение всего времени копирования файла исполняющий поток занят копированием файла, а не прокачкой очереди сообщений.Хотя это WinForms, а не Win32, WinForms представляет собой относительно легкую оболочку для стандартной среды Win32 GUI.Вашу очередь сообщений необходимо регулярно обслуживать, поэтому все выполняющиеся задачи необходимо запускать из потока пользовательского интерфейса.

И последнее замечание: помните, что когда вы получаете обратный вызов прогресса, вам нужно использовать Invokeили BeginInvoke при обновлении любого пользовательского интерфейса.Это связано с тем, что код, который обновляет пользовательский интерфейс, должен запускаться из потока пользовательского интерфейса.

...