从 c++/cx 中的回调内部调用 UI 线程上的问题
Issue calling something on the UI Thread from inside a callback in c++/cx
这是我的回调函数:
void VideoCapturerSampleCallback(struct LmiVideoCapturer_* capturer, const LmiVideoFrame* videoFrame, LmiVoidPtr userData)
{
//TODO will have to be on ui thread;
Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(0, ref new Windows::UI::Core::DispatchedHandler([this]()
{
Windows::UI::Xaml::Media::Imaging::BitmapImage^ bitmapImage =
ref new Windows::UI::Xaml::Media::Imaging::BitmapImage();
auto uri = ref new Windows::Foundation::Uri("ms-appx:///Assets/1.jpg");
if (first){
first = false;
}
else{
uri = ref new Windows::Foundation::Uri("ms-appx:///Assets/1.jpg");
first = true;
}
bitmapImage->UriSource = uri;
media->Source = bitmapImage;
}));
}
基本上每次调用回调都会换图片,目前我只是从Assets换了2张图片,看看能不能用。
这是我在日志中得到的错误:
Error 17 error C1903: unable to recover from previous error(s); stopping compilation C:\Users\Alin Rosu\Downloads\App2\App2\MainPage.xaml.cpp 109 1 App2
Error 16 error C3482: 'this' can only be used as a lambda capture within a non-static member function C:\Users\Alin Rosu\Downloads\App2\App2\MainPage.xaml.cpp 93 1 App2
19 IntelliSense: 'this' may only be used inside a nonstatic member function c:\Users\Alin Rosu\Downloads\App2\App2\MainPage.xaml.cpp 93 144 App2
18 IntelliSense: function "Windows::UI::Core::CoreDispatcher::RunAsync" cannot be called with the given argument list
argument types are: (int, Windows::UI::Core::DispatchedHandler ^)
object type is: Windows::UI::Core::CoreDispatcher ^ c:\Users\Alin Rosu\Downloads\App2\App2\MainPage.xaml.cpp 93 84 App2
现在是否可以在回调中使用 [this] 而不会出错?
我是一名 Android 开发人员,所以对我来说,对此的逻辑响应是创建一个全局变量 App2::MainPage,然后在构造函数中,将 "this" 保存在其中,这样我就可以那里的上下文,并尝试用它调用 RunAsync,但它不起作用。
是否可以通过其他方式实例化 DispatchedHandler?
这样声明上下文:
App2::MainPage^ context;
然后在MainPage函数中设置:
MainPage::MainPage()
{
InitializeComponent();
media = this->player;
context = this;
}
然后我在 VideoCapturerSampleCallback 中这样做:
void VideoCapturerSampleCallback(struct LmiVideoCapturer_* capturer, const LmiVideoFrame* videoFrame, LmiVoidPtr userData)
{
App2::MainPage^ ctx = context;
Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new Windows::UI::Core::DispatchedHandler([ctx]()
{
//TODO will need to set in here
Windows::UI::Xaml::Media::Imaging::BitmapImage^ bitmapImage =
ref new Windows::UI::Xaml::Media::Imaging::BitmapImage();
auto uri = ref new Windows::Foundation::Uri("ms-appx:///Assets/1.jpg");
if (first){
XTRACE(L"===================FIIIIIIIIIIIIRST =======================\n");
first = false;
}
else{
XTRACE(L"===================FIIIIIIIIIIIIRST FAAAALSEEEEE=======================\n");
uri = ref new Windows::Foundation::Uri("ms-appx:///Assets/2.jpg");
first = true;
}
bitmapImage->UriSource = uri;
media->Source = bitmapImage;
}));
}
这解决了我的问题,我可以修改 UI,在 UI 线程上。
这是我的回调函数:
void VideoCapturerSampleCallback(struct LmiVideoCapturer_* capturer, const LmiVideoFrame* videoFrame, LmiVoidPtr userData)
{
//TODO will have to be on ui thread;
Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(0, ref new Windows::UI::Core::DispatchedHandler([this]()
{
Windows::UI::Xaml::Media::Imaging::BitmapImage^ bitmapImage =
ref new Windows::UI::Xaml::Media::Imaging::BitmapImage();
auto uri = ref new Windows::Foundation::Uri("ms-appx:///Assets/1.jpg");
if (first){
first = false;
}
else{
uri = ref new Windows::Foundation::Uri("ms-appx:///Assets/1.jpg");
first = true;
}
bitmapImage->UriSource = uri;
media->Source = bitmapImage;
}));
}
基本上每次调用回调都会换图片,目前我只是从Assets换了2张图片,看看能不能用。 这是我在日志中得到的错误:
Error 17 error C1903: unable to recover from previous error(s); stopping compilation C:\Users\Alin Rosu\Downloads\App2\App2\MainPage.xaml.cpp 109 1 App2
Error 16 error C3482: 'this' can only be used as a lambda capture within a non-static member function C:\Users\Alin Rosu\Downloads\App2\App2\MainPage.xaml.cpp 93 1 App2
19 IntelliSense: 'this' may only be used inside a nonstatic member function c:\Users\Alin Rosu\Downloads\App2\App2\MainPage.xaml.cpp 93 144 App2
18 IntelliSense: function "Windows::UI::Core::CoreDispatcher::RunAsync" cannot be called with the given argument list
argument types are: (int, Windows::UI::Core::DispatchedHandler ^)
object type is: Windows::UI::Core::CoreDispatcher ^ c:\Users\Alin Rosu\Downloads\App2\App2\MainPage.xaml.cpp 93 84 App2
现在是否可以在回调中使用 [this] 而不会出错? 我是一名 Android 开发人员,所以对我来说,对此的逻辑响应是创建一个全局变量 App2::MainPage,然后在构造函数中,将 "this" 保存在其中,这样我就可以那里的上下文,并尝试用它调用 RunAsync,但它不起作用。 是否可以通过其他方式实例化 DispatchedHandler?
这样声明上下文:
App2::MainPage^ context;
然后在MainPage函数中设置:
MainPage::MainPage()
{
InitializeComponent();
media = this->player;
context = this;
}
然后我在 VideoCapturerSampleCallback 中这样做:
void VideoCapturerSampleCallback(struct LmiVideoCapturer_* capturer, const LmiVideoFrame* videoFrame, LmiVoidPtr userData)
{
App2::MainPage^ ctx = context;
Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new Windows::UI::Core::DispatchedHandler([ctx]()
{
//TODO will need to set in here
Windows::UI::Xaml::Media::Imaging::BitmapImage^ bitmapImage =
ref new Windows::UI::Xaml::Media::Imaging::BitmapImage();
auto uri = ref new Windows::Foundation::Uri("ms-appx:///Assets/1.jpg");
if (first){
XTRACE(L"===================FIIIIIIIIIIIIRST =======================\n");
first = false;
}
else{
XTRACE(L"===================FIIIIIIIIIIIIRST FAAAALSEEEEE=======================\n");
uri = ref new Windows::Foundation::Uri("ms-appx:///Assets/2.jpg");
first = true;
}
bitmapImage->UriSource = uri;
media->Source = bitmapImage;
}));
}
这解决了我的问题,我可以修改 UI,在 UI 线程上。