Now I'm trying to use PropertyChangedEvent to test update the textblock, but when I click, it crashed: WinRT originate error - 0x8001010E : The application called an interface that was marshalled for a different thread.
//in WordArray.cpp
namespace winrt::Lexical_Frequency::implementation
{
WordArray::WordArray(winrt::hstring const& allword) : m_allword{ allword }
{
}
winrt::hstring WordArray::AllWord()
{
return m_allword;
}
void WordArray::AllWord(winrt::hstring const& value)
{
if (m_allword != value)
{
m_allword = value;
m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"AllWord" });
}
}
winrt::event_token WordArray::PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
{
return m_propertyChanged.add(handler);
}
void WordArray::PropertyChanged(winrt::event_token const& token)
{
m_propertyChanged.remove(token);
}
}
//in DataPage.xaml.cpp
namespace winrt::Lexical_Frequency::implementation
{
DataPage::DataPage()
{
m_mainviewModel = winrt::make<Lexical_Frequency::implementation::WordArrayViewModel>();
InitializeComponent();
}
void DataPage::ClickHandler(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e)
{
MainViewModel().WordArray().AllWord(L"xxx");
}
void DataPage::SaveFileButton_Click(IInspectable const&, RoutedEventArgs const&)
{
GetFileNameSave();
}
Lexical_Frequency::WordArrayViewModel DataPage::MainViewModel()
{
return m_mainviewModel;
}
}
Now I'm trying to use MainViewModel().WordArray().AllWord(L"To Kill a Mockingbird"); to test update the textblock, but when I click, it crashed: WinRT originate error - 0x8001010E : The application called an interface that was marshalled for a different thread.
You'll frequently encounter this error when dropping code written for Microsoft's "Modern" UI platform (that never got a name) into a WinUI 3 application.
A bit of historic context: Alongside the "Modern" UI platform, Windows 8 introduced a variation of the STA, the Application STA (wildly undocumented1, no surprises there). Windows 10 finally exposed the "Modern" UI platform (still unnamed) through Windows Runtime types under the Windows.UI.Xaml
namespace. (Most) of those types will want to be accessed from the ASTA (which is apparently enforced at run time, evidenced by the RPC_E_WRONG_THREAD
"exception").
Fast forward to today, the "Modern" UI platform mostly gone, together with its clean design language. The UWP sharing a coffin with Windows 10 Mobile, and the ASTA history, too. WinUI 3 has come full circle, ultimately supporting the classic Desktop application model only, back to the classic COM threading architecture: Zero or one MTA, and any number of STAs.
No ASTA, anywhere.
After that bit of a detour it should be easy to understand, what the issue is: The code is trying to access objects designed for the ASTA from a regular STA thread.
The solution is pretty straight forward, too: Replace all types from the Windows.UI.Xaml
namespace with their WinUI 3 twins from the Microsoft.UI.Xaml
namespace:
WordArray
make sure to derive from Microsoft.UI.Xaml.Data.INotifyPropertyChanged
rather than Windows.UI.Xaml.Data.INotifyPropertyChanged
winrt::event
class template from Windows::UI::Xaml::Data::PropertyChangedEventHandler
to Microsoft::UI::Xaml::Data::PropertyChangedEventHandler
and update the PropertyChanged
implementations to use this type as wellMicrosoft::UI::Xaml::Data::PropertyChangedEventArgs
object instead of a Windows::UI::Xaml::Data::PropertyChangedEventArgs
object when raising eventsTo do this you will also have to update the respective #include
directives that reference <winrt/Windows.UI.Xaml. ... .h>
header files to use <winrt/Microsoft.UI.Xaml. ... .h>
instead, and replace any using namespace
directives accordingly.
1 Raymond Chen explains what problem it is trying to solve in his blog entry What is so special about the Application STA?.