Вы спрашиваете "не подразумевается ли, что им манипулируют в потоке пользовательского интерфейса". Ничто не дает абсолютной гарантии, так как Майк указывает, что точки входа не частного кода могут быть вызваны не в потоке пользовательского интерфейса.
Однако вы можете быть уверены, что событие, поступающее от элементов пользовательского интерфейса, будет в потоке пользовательского интерфейса.
Что касается принятия любых мер предосторожности для обеспечения работы вашего кода в потоке пользовательского интерфейса, я не думаю, что это разумно. Что произойдет, если вы просто позволите коду работать нормально. Возможно, это удастся, потому что вы на самом деле не взаимодействуете с элементом пользовательского интерфейса, никакого вреда. В качестве альтернативы код продолжается и выдает исключение. Это плохо?
Использование предосторожности BeginInvoke
приводит к тому, что вызывающий код завершается асинхронно с вызванным кодом манипулирования пользовательским интерфейсом. Это может привести к непредсказуемому результату, который может стать кошмаром для выслеживания. Намного лучше, чтобы ваш код вел себя предсказуемо. Просто верните ошибку обратно в код, который должен нести ответственность за вызов компонента пользовательского интерфейса в правильном потоке. После того, как весь код выполняется как часть компонента пользовательского интерфейса, такого как UserControl
или Page
.
Учтите также, что существующие элементы пользовательского интерфейса в среде выполнения, SDK и инструментарии не выполняют предупредительное переключение потоков.
Редактировать: ответ на дерзкое добавление второстепенного вопроса
Это зависит от используемого вами Async API и от того, в каком потоке был вызван API.
Когда вы вызываете асинхронный метод WebClient
из потока пользовательского интерфейса, соответствующее событие также возникает в потоке пользовательского интерфейса. Аналогичным образом, если вы используете клиентский класс службы WCF, событие Completed будет вызываться в потоке пользовательского интерфейса, если асинхронная операция первоначально вызывается в потоке пользовательского интерфейса.
Однако при использовании пар Begin / End в компоненте WebRequest (или стандартном интерфейсе службы из WCF) обратные вызовы будут выполняться в фоновом потоке независимо от исходного потока, использованного для запуска операции.