Skip to content

UI thread crash in WPF when using RTC SDK #529

@fan-van

Description

@fan-van

Title:
UI thread crash in WPF after multiple join/leave operations with specific camera

Environment:
Platform: WPF (.NET)
Device: PC with two cameras
SDK: [please fill in RTC SDK name and version]

Steps to Reproduce:

  1. Use a device that has two cameras.
  2. Start an audio/video call by calling JoinChannel, and specify one of the cameras explicitly.
  3. Leave the channel.
  4. Repeat step 2 and 3 multiple times (typically 7–8 times).

Actual Result:

  • After several join/leave cycles, the WPF application crashes, and the UI thread stops responding.
  • Exception details:
    System.InvalidCastException
    HResult=0x80004002
    Message=Unable to cast object of type 'System.__ComObject' to type 'ITfThreadMgr'.

Expected Result:
The application should remain stable even after repeatedly joining and leaving the channel.

Notes:

  • The issue only appears when a specific camera is selected.

  • If both cameras are available but not explicitly specified, the problem is less frequent.

  • Related code excerpt:

    public override int JoinChannel(string? token, string channelId, bool localVideo, bool localAudio)
    {
    
        this.channelId = channelId;
        LogStateChange(prev, _state, "开始加入频道");
    
        try
        {
    
            // Accessing the video device manager and enumerating video devices here
            // causes UI thread issues when called in WPF after multiple join/leave cycles.
    
            var manager = rtc_engine_.GetVideoDeviceManager();
             var list = manager.EnumerateVideoDevices();
    
            if (list.Length > 1)
            {
                var temp = list[1];
                var result = manager.SetDevice(temp.deviceId);
            }
    
            rtc_engine_.EnableVideo();
            rtc_engine_.EnableAudio();
            rtc_engine_.EnableLocalVideo(localVideo);
            rtc_engine_.EnableLocalAudio(localAudio);
    
            rtc_engine_.StartPreview(VIDEO_SOURCE_TYPE.VIDEO_SOURCE_CAMERA_PRIMARY);
    
            ChannelMediaOptions options = new ChannelMediaOptions();
            options.publishCameraTrack.SetValue(localVideo);
            options.publishMicrophoneTrack.SetValue(localAudio);
            options.channelProfile.SetValue(CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_LIVE_BROADCASTING);
            options.clientRoleType.SetValue(CLIENT_ROLE_TYPE.CLIENT_ROLE_BROADCASTER);
    
            var realChannel = (channelId.Split(';').GetValue(0) ?? string.Empty).ToString();
            var ret = rtc_engine_.JoinChannel(token, realChannel, 0, options);
            this.LogInfo($"JoinChannel Agora 调用 ret={ret}, realChannel={realChannel}");
    
            if (ret != 0)
            {
                _state = EngineState.Initialized;
                return ret;
            }
    
            rtc_engine_.EnableAudioVolumeIndication(300, 3, false);
            return ret;
        }
        catch (Exception ex)
        {
            _state = EngineState.Initialized;
            return -1;
        }
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions