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

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    No status

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions