Open DierkDroth opened 2 days ago
Just to ask, since it may be obvious for you but not for me. Is this a C++ project or a C# project? I think the "VS update last week" implies C#, but it would be nice to have the language explicitly stated.
Just to ask, since it may be obvious for you but not for me. Is this a C++ project or a C# project? I think the "VS update last week" implies C#, but it would be nice to have the language explicitly stated.
@DarranRowe sorry I forgot to be specific and just amended the case description: this is C# on .NET8
At least for the build time change, this might be related to our source generator / analyzer in the Windows SDK projection having a perf impact on larger projects. We do have an updated Windows SDK projection package coming in next month's .NET SDK update with some performance improvements to the generator that I am hoping may help here. If you want to try out the change manually before it is in the .NET SDK, see here for the WindowsSdkPackageVersion
to specify.
Thanks for your feedback @manodasanW.
Honestly I have no clue why I would need source generators / analyzers or even any "projection" on building (!) a solution.
Isn't there a way to get rid of all that? If so, what exactly would I need to do?
BTW I have these settings since ever, because I don't need all that stuff
Thanks for your feedback @manodasanW.
Honestly I have no clue why I would need source generators / analyzers or even any "projection" on building (!) a solution.
Isn't there a way to get rid of all that? If so, what exactly would I need to do?
For the projection, the answer is yes, but you honestly don't want to do that.
The Windows App SDK is a set of Windows Runtime components. Windows Runtime components are an evolution of COM. The projection is to make them much easier to use by mapping them to a more natural construct for the language. Without the projection, the components would have to be accessed via the ABI, which is more akin to accessing COM components.
I have had to do that in a C++ project, there was a need to access some Windows App SDK functionality but I was unable to use C++/WinRT (this is the recommended C++ projection). The equivalent of the following:
auto dispqueuec = winrt::Microsoft::UI::Dispatching::DispatcherQueueController::CreateOnCurrentThread();
ended up being:
template <typename Interface, typename RuntimeClass>
struct interface_traits
{
static_assert(static_assert_helper<Interface>::value, "interface_traits is not specialised for this interface");
};
template <typename Interface, typename RuntimeClass>
struct factory_interface_traits
{
static_assert(static_assert_helper<Interface>::value, "factory_interface_traits is not specialised for this interface");
};
template <>
struct interface_traits<ABI::Microsoft::UI::Dispatching::IDispatcherQueueController, ABI::Microsoft::UI::Dispatching::DispatcherQueueController>
{
using type = ABI::Microsoft::UI::Dispatching::IDispatcherQueueController;
using base_type = ABI::Microsoft::UI::Dispatching::IDispatcherQueueController;
using class_type = ABI::Microsoft::UI::Dispatching::DispatcherQueueController;
inline static constexpr std::wstring_view class_name{ init_stringview(RuntimeClass_Microsoft_UI_Dispatching_DispatcherQueueController) };
inline static constexpr std::wstring_view interface_name{ init_stringview(InterfaceName_Microsoft_UI_Dispatching_IDispatcherQueueController) };
inline static constexpr bool activatable = false;
};
template <>
struct factory_interface_traits<ABI::Microsoft::UI::Dispatching::IDispatcherQueueControllerStatics, ABI::Microsoft::UI::Dispatching::DispatcherQueueController>
{
using type = ABI::Microsoft::UI::Dispatching::IDispatcherQueueControllerStatics;
using class_type = ABI::Microsoft::UI::Dispatching::DispatcherQueueController;
inline static constexpr std::wstring_view class_name{ init_stringview(RuntimeClass_Microsoft_UI_Dispatching_DispatcherQueueController) };
inline static constexpr std::wstring_view interface_name{ init_stringview(InterfaceName_Microsoft_UI_Dispatching_IDispatcherQueueControllerStatics) };
};
inline Microsoft::WRL::Wrappers::HString initialise_hstring(const std::wstring_view &runtime_class)
{
HRESULT hr = S_OK;
Microsoft::WRL::Wrappers::HString hs;
hr = hs.Set(runtime_class.data());
RoOriginateErrorW(hr, 0, L"Failed to set the runtime class name");
THROW_IF_FAILED(hr);
return hs;
}
template <typename Interface, typename RuntimeClass>
inline auto get_activation_factory()
{
HRESULT hr = S_OK;
Microsoft::WRL::ComPtr<Interface> ret;
auto runtime_class = initialise_hstring(factory_interface_traits<Interface, RuntimeClass>::class_name);
hr = Windows::Foundation::GetActivationFactory(runtime_class, ret.ReleaseAndGetAddressOf());
if (FAILED(hr))
{
#if (__cplusplus >= 202002L || (defined _MSVC_LANG && _MSVC_LANG >= 202002L))
auto l_fmtstr = application::helper::format_to_string(L"Failed to get activation factory. Interface name: {}, RuntimeClass name: {}", factory_interface_traits<Interface, RuntimeClass>::interface_name, factory_interface_traits<Interface, RuntimeClass>::class_name);
#else
auto l_fmtstr = application::helper::format_to_string(L"Failed to get activation factory. Interface name: %s, RuntimeClass name: %s", factory_interface_traits<Interface, RuntimeClass>::interface_name.data(), factory_interface_traits<Interface, RuntimeClass>::class_name.data());
#endif
RoOriginateErrorW(hr, static_cast<UINT>(l_fmtstr.length()), l_fmtstr.c_str());
THROW_IF_FAILED(hr);
}
return ret;
}
...
//Create dispatcher queue function
...
ComPtr<IDispatcherQueueController> disp_queue_ctrl;
auto dqcs = wrl_helpers::get_activation_factory<IDispatcherQueueControllerStatics, DispatcherQueueController>();
THROW_IF_FAILED(dqcs->CreateOnCurrentThread(disp_queue_ctrl.ReleaseAndGetAddressOf()));
...
I could have made it more compact if it was just using the ABI to access the Windows App SDK DispatcherQueue, but I was using some other Windows Runtime components through the ABI so I just added onto what I had.
This highlights two important things. First, using these components through the ABI requires a lot of code, and a lot of it is shared. Secondly, the components are usable for multiple languages.
@DarranRowe thanks for your feedback.
Here is my layman's thinking: What you said is well and fine. Sure, I wanted to have easy-to-use 'wrappers' in my C# environment. But:
Also, I'm sure there must have been something to the same effect with <= WindowsAppSDK 1.5. Why would WindowsAppSDK 1.6 performance be worse in that regard?
Describe the bug
With last VS update last week I updated my C# .NET8 solution from WindowsAppSDK 1.5 to WindowsAppSDK 1.6.
Unfortunately this increased the build time drastically: e.g. a project which includes a WindowsAppSDK shared project now takes at least 3 times as long to build as before. Obviously this increased turn around time drastically and slows down the development cycle. I never experienced something like at on any prior WindowsAppSDK update.
How could I go back to the prior building cycle turn arounds?
I also experienced - but this is nothing new though - that building the solution again without something being changed (!) e.g. just by pressing F5 goes through new compiler runs. Why are the building tools (compiler etc.) not aware that nothing was changed?
Please don't ask me for a repo. Demonstrating the issue requires a solution with a substantial number of source files.
Steps to reproduce the bug
Please see above
Expected behavior
No response
Screenshots
No response
NuGet package version
None
Packaging type
No response
Windows version
No response
IDE
No response
Additional context
No response