1) Не указывайте RunWorkerAsync
в качестве вызываемого метода. На самом деле это не тот метод, о котором вы думаете. То, что вы действительно должны поместить там, выглядит примерно так:
this.Invoke(new MethodInvoker(MethodToUpdateUI));
MethodToUpdateUI
должен быть какой-то новый метод, который вы создаете, который специально делает все обновления пользовательского интерфейса, которые должны быть сделаны в этом контексте.
2) Нет необходимости в InvokeRequired
. Вы находитесь в фоновом потоке. Вызов всегда будет требоваться.
Честно говоря, весь паттерн if(invoke required) call myself else do stuff
— странная конструкция, которая мне не нравится. InvokeRequired
следует использовать довольно редко. Вы почти всегда должны знать, находитесь ли вы в потоке пользовательского интерфейса или в фоновом потоке, если нет, скорее всего, что-то не так (либо вы всегда находитесь в одном, либо в другом, и вы просто не знаете, в каком, или это не должно быть недетерминированным). Обычно это означает наличие методов, которые должны выполняться в потоке пользовательского интерфейса. Если вы уже находитесь в потоке пользовательского интерфейса, вы просто вызываете их, если вы находитесь в фоновом потоке и знаете это, тогда вы сначала вызываете Invoke
.
Кроме того, Invoke
работает просто отлично, даже если вы вызываете его, когда вы уже находитесь в потоке пользовательского интерфейса, поэтому на самом деле нет серьезных негативных последствий для простого вызова Invoke
независимо от того, находитесь ли вы в фоновом потоке или уже в пользовательском интерфейсе. нить.
3) Обычно код для решения бизнес-задач лучше отделить от кода пользовательского интерфейса. Это запах кода, который нужно вызывать из обработчика DoWork. Если это почти конец, вам, вероятно, следует добавить обработчик событий в RunWorkerCompleted
. Если вы периодически вызываете это, чтобы обновить пользовательский интерфейс с ходом работы работника, вы должны использовать ReportProgress
и обрабатывать событие ProgressReported
. Чтобы получить информацию из пользовательского интерфейса для использования в длительной задаче, вы должны получить к ней доступ перед запуском фоновой задачи. Для исключительных случаев, которые не являются ни одним из них, может быть уместно использовать Invoke
, но остальные случаи должны быть редкими.
person
Servy
schedule
19.12.2012
bw.RunWorkerAsync
изbw.DoWork
? - person Mike Park   schedule 20.12.2012