Calling DllGetClassObject on comhost is extremely slow because get_com_delegate is called for every call of DllGetClassObject.
Calling get_com_delegate leads to parsing of runtimeconfig.json etc.
We hit this performance issue after upgrading from .NET 4.8 to .NET 10.
In our case we have C++ code which creates COM objects implemented in C# in more or less tight loops.
Real world performance of our application, for this usage scenario, is decreased by a factor of 3 just because of this.
We implemented a temporary workaround by building our own comhost and using that instead of the .NET provided one.
Our solution was to guard calls to get_com_delegate and only call it once per comhost.
"Fixed" code now is:
clsid_map::const_iterator iter = map.find(rclsid);
if (iter == std::end(map))
return CLASS_E_CLASSNOTAVAILABLE;
HRESULT hr;
static pal::mutex_t was_loaded_lock;
static bool was_loaded;
static pal::string_t app_path;
static com_delegates act;
static void* load_context;
{
std::lock_guard<pal::mutex_t> lock{ was_loaded_lock };
if (was_loaded == false)
{
trace::setup();
reset_redirected_error_writer();
error_writer_scope_t writer_scope(redirected_error_writer);
int ec = get_com_delegate(hostfxr_delegate_type::hdt_com_activation, &app_path, act, &load_context);
if (ec != StatusCode::Success)
{
report_com_error_info(rclsid, std::move(get_redirected_error_string()));
return __HRESULT_FROM_WIN32(ec);
}
assert(act.delegate != nullptr || load_context == ISOLATED_CONTEXT);
was_loaded = true;
}
}
// Query the CLR for the type
IUnknown *classFactory = nullptr;
I am not sure if that might have any undesired side effects like memory leaks etc.
Would be nice if our fix could either be incorporated, even if it was changed for a better solution or if at least an area expert could validate our solution.
Calling
DllGetClassObjecton comhost is extremely slow becauseget_com_delegateis called for every call ofDllGetClassObject.Calling
get_com_delegateleads to parsing of runtimeconfig.json etc.We hit this performance issue after upgrading from .NET 4.8 to .NET 10.
In our case we have C++ code which creates COM objects implemented in C# in more or less tight loops.
Real world performance of our application, for this usage scenario, is decreased by a factor of 3 just because of this.
We implemented a temporary workaround by building our own comhost and using that instead of the .NET provided one.
Our solution was to guard calls to
get_com_delegateand only call it once per comhost."Fixed" code now is:
I am not sure if that might have any undesired side effects like memory leaks etc.
Would be nice if our fix could either be incorporated, even if it was changed for a better solution or if at least an area expert could validate our solution.