2012-08-09 3 views
0

Я реализую потоки в режиме метро, ​​я получил этот пример в Google, но я не понимаю CallbackContext. Какая польза от этого? This объясняет его использование в MTA, но не ясно. И я столкнулся с проблемой, когда использую CallbackContext как Any или Same. Что-то работает с одним, но не с другим! Итак, прежде всего, я хочу знать, в чем польза от этого ?! PS: Я новичок в программировании WindowsRT и C++ тоже! Благодаря!Делегаты и поток: CallbackContext параметр

auto workItemHandler = ref new WorkItemHandler([=](IAsyncAction^) 
{ 
    // Run the user callback. 
    try 
    { 
     func(data); 
    } 
    catch (...) 
    { 

    } 
    // Signal that the thread has completed. 
    SetEvent(completionEvent); 
    //CloseHandle(completionEvent); 

}, CallbackContext::Same); 

ответ

2

CallbackContext определяет (в данном случае, WorkItemHandler) агрегирует ли ваш делегат свободной нарезки маршаллера. Это определит, может ли ваш делегат быть контрабандным путем в другую квартиру (CallbackContext::Any), или если он должен быть возвращен в исходную квартиру (CallbackContext::Same). В основном, это говорит человеку, вызывающему вашего делегата, может ли он быть вызван напрямую, независимо от квартиры, или если им нужно отправить марш в квартиру, в которой он был создан.

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

Однако, если вам нужно изменить пользовательский интерфейс или сделать обратный вызов в пользовательском интерфейсе, и вы попытаетесь сделать это из потока, отличного от UI, вы получите неверное исключение потока. Добавив параметр CallbackContext::Same, вы можете заставить своего делегата работать в исходной квартире (в этом случае, STA) и тем самым избежать проблемы.

(Вы также можете сделать обратный вызов в потоке пользовательского интерфейса, используя Dispatcher->RunAsync, чтобы вызвать дополнительный делегат для запуска в STA. Лучше ли для всего вашего делегата работать в STA или нет, зависит от вашего сценария.)