CallbackContext
определяет (в данном случае, WorkItemHandler
) агрегирует ли ваш делегат свободной нарезки маршаллера. Это определит, может ли ваш делегат быть контрабандным путем в другую квартиру (CallbackContext::Any
), или если он должен быть возвращен в исходную квартиру (CallbackContext::Same
). В основном, это говорит человеку, вызывающему вашего делегата, может ли он быть вызван напрямую, независимо от квартиры, или если им нужно отправить марш в квартиру, в которой он был создан.
Например, в приложении для Windows Store все, что изменяет пользовательский интерфейс должен работать в потоке пользовательского интерфейса (STA). Предположим, что вы используете метод, который работает в потоке пользовательского интерфейса (например, обратный вызов события, например, обработчик нажатия кнопки). Некоторые асинхронные вызовы, такие как ThreadPool::RunAsync
, будут запускать переданный делегат в потоке другой, чем поток пользовательского интерфейса (по умолчанию для делегатов CallbackContext::Any
). Это полезно, если вам не нужно ничего делать в потоке пользовательского интерфейса, так как он освобождает этот поток, чтобы продолжить перекачку сообщений (и ваше приложение продолжает чувствовать себя работоспособным).
Однако, если вам нужно изменить пользовательский интерфейс или сделать обратный вызов в пользовательском интерфейсе, и вы попытаетесь сделать это из потока, отличного от UI, вы получите неверное исключение потока. Добавив параметр CallbackContext::Same
, вы можете заставить своего делегата работать в исходной квартире (в этом случае, STA) и тем самым избежать проблемы.
(Вы также можете сделать обратный вызов в потоке пользовательского интерфейса, используя Dispatcher->RunAsync
, чтобы вызвать дополнительный делегат для запуска в STA. Лучше ли для всего вашего делегата работать в STA или нет, зависит от вашего сценария.)