Skip to content

DllGetClassObject on comhost is extremely slow #130251

Description

@batzen

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status
    No status

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions