SmartClient Hang

We have a SmartClient plugin, and in the background code, we have registered for NewImageViewerControlEvent.

We are changing the camera for the imageviewer by using PostMessage.

When the recording server is not running, the entire SmartClient hangs after a few seconds. But no hang is observed when the recording server is running, and the cameras are offline or disabled.

Can we know why SmartClient hangs when the recording server is offline?

Below is the sample code to reproduce the issue.

MIPSDK - 24.2.3

Milestone XProtect Version - 2024 R2

public override void Init() 
{
ClientControl.Instance.NewImageViewerControlEvent += Instance_NewImageViewerControlEvent;
}
 
private void Instance_NewImageViewerControlEvent(ImageViewerAddOn imageViewerAddOn)
{
    if (imageViewerAddOn == null || imageViewerAddOn.ImageViewerType == ImageViewerType.MIP)
    {
        System.Diagnostics.Trace.WriteLine("NewImageViewerControlEvent: Ignoring MIP or null ImageViewer ");
        return;
    }
	FQID fqid = imageViewerAddOn.CameraFQID;
 
 
	BackgroundWorker backgroundWorker = new BackgroundWorker();
	backgroundWorker.DoWork += (s, e) =>
	{
		Thread.Sleep(5000); // Initial delay before starting the timer
		if(Camera1.FQID == fqid)
			fqid = Camera2.FQID;
		else
			fqid = Camera1.FQID;
		EnvironmentManager.Instance.PostMessage(new VideoOS.Platform.Messaging.Message(MessageId.SmartClient.SetCameraInViewCommand, new SetCameraInViewCommandData()
		{
			Index = imageViewerAddOn.ViewItemIndex,
			CameraFQID = fqid, 
			StreamId = Guid.Empty
		}));
	};
	backgroundWorker.RunWorkerAsync();
    
}

I created a small plugin using your code, I experienced some NullReference exceptions that I did not look into, I assume you have found those if you have them in your plugin.

In my testing I found that your plugin works exactly the same way whether the Recording Server (RS) is running or not. If RS does not run the cameras still change, only to display the error “Connecting…”

If you look in the Smart Client logs are there any clues? (Enable logging in Settings → Advanced)

We can always reproduce this issue. We are getting the following error in MIPLog.

2026-01-08 21:52:38.009-08:00 [ 1] DEBUG - Debug: NewImageViewerControlEvent (IncidentManagerBackgroundPlugin):starting function

2026-01-08 21:52:38.128-08:00 [ 1] DEBUG - Debug: NewImageViewerControlEvent (IncidentManagerBackgroundPlugin):starting function

2026-01-08 21:52:38.141-08:00 [ 1] DEBUG - Debug: NewImageViewerControlEvent (IncidentManagerBackgroundPlugin):starting function

2026-01-08 21:52:38.164-08:00 [ 1] DEBUG - Debug: NewImageViewerControlEvent (IncidentManagerBackgroundPlugin):starting function

2026-01-08 21:53:03.917-08:00 [ 88] DEBUG - …Exception:Error reading from stream! at VideoOS.Toolkit.LiveSourceToolkit.GetLiveData(IData& data, TimeSpan timeout)

at VideoOS.Platform.Common.InternalMediaServiceCommon.LiveGet(Object sessionId, TimeSpan waitTime, Boolean rawData)

2026-01-08 21:53:03.917-08:00 [ 88] DEBUG - Debug: LiveGet ():Error reading from stream!

2026-01-08 21:53:03.917-08:00 [ 88] DEBUG - …Exception:Error reading from stream! at VideoOS.Platform.Common.InternalMediaServiceCommon.LiveGet(Object sessionId, TimeSpan waitTime, Boolean rawData)

at VideoOS.Platform.Common.InternalMediaServiceCommon.LiveGet(Object sessionId, TimeSpan waitTime)

at VideoOS.Platform.Live.MetadataLiveSource.PollThread()

2026-01-08 21:53:03.917-08:00 [ 88] DEBUG - Error: MetadataLiveSource:PollThread ():Error reading from stream!

2026-01-08 21:53:03.921-08:00 [ 57] DEBUG - …Exception:Error reading from stream! at VideoOS.Toolkit.LiveSourceToolkit.GetLiveData(IData& data, TimeSpan timeout)

at VideoOS.Platform.Common.InternalMediaServiceCommon.LiveGet(Object sessionId, TimeSpan waitTime, Boolean rawData)

2026-01-08 21:53:03.921-08:00 [ 57] DEBUG - Debug: LiveGet ():Error reading from stream!

2026-01-08 21:53:03.923-08:00 [ 57] DEBUG - …Exception:Error reading from stream! at VideoOS.Platform.Common.InternalMediaServiceCommon.LiveGet(Object sessionId, TimeSpan waitTime, Boolean rawData)

at VideoOS.Platform.Common.InternalMediaServiceCommon.LiveGet(Object sessionId, TimeSpan waitTime)

at VideoOS.Platform.Live.MetadataLiveSource.PollThread()

2026-01-08 21:53:03.923-08:00 [ 57] DEBUG - Error: MetadataLiveSource:PollThread ():Error reading from stream!

2026-01-08 21:53:06.400-08:00 [ 1] DEBUG - Debug: NewImageViewerControlEvent (IncidentManagerBackgroundPlugin):starting function

2026-01-08 21:53:06.409-08:00 [ 1] DEBUG - Error: SendMessage ():Exception source: VideoOS.Toolkit

Exception type: VideoOS.Toolkit.NotConnectedException

Exception message: Not connected to toolkit!

Exception target site: DoLive

at VideoOS.Toolkit.AudioToolkit.DoLive()

at VideoOS.Platform.Common.Audio.NAudioPlayerComponent.LiveStart()

at VideoOS.RemoteClient.Application.ExtensionPlugins.Audio.AudioExtensionPlugin.StartAudio()

at VideoOS.RemoteClient.Application.ExtensionPlugins.Audio.AudioExtensionPlugin.TryToActivateRelatedAudioDevices(IReadOnlyCollection`1 relatedMicrophones, IReadOnlyCollection`1 relatedSpeakers)

at VideoOS.RemoteClient.Application.ExtensionPlugins.Audio.AudioExtensionPlugin.TryToActivateRelatedAudioDevices()

at VideoOS.RemoteClient.Application.Controllers.ViewSelection.SelectedViewItemChangedEventHandler.Invoke(Object sender, SelectedViewItemChangedEventArgs e)

at VideoOS.RemoteClient.Application.Controllers.ViewSelection.ApplicationViewSelectionObserver.ViewSelectionSetter.<>c__DisplayClass3_0.b__1()

at VideoOS.RemoteClient.Application.Controllers.ViewSelection.WindowViewSelectionObserver.ViewSelectionSetter.<>c__DisplayClass4_0.b__1()

at VideoOS.RemoteClient.Application.Controllers.ViewSelection.WorkroomViewSelector.OnSelectionChanged(View oldView, Boolean selectedViewItemChanged, SelectionSetterLevel selectionSetterLevel)

at VideoOS.RemoteClient.Application.UI.Content.Grid.ContentGrid.ShowViewItemTemporarily(Int32 gridIndex, ViewItemBase viewItem, Boolean keepViewItemSelection)

at VideoOS.RemoteClient.Application.UI.Content.Grid.ContentGrid.ShowCameraTemporarily(Int32 gridIndex, Guid cameraId, Guid streamId)

at VideoOS.RemoteClient.Application.MIP.Manager.ViewConfigurationManager.SetCameraInView(FQID fqid, Int32 ix, Guid cameraId, Guid streamId)

at VideoOS.RemoteClient.Application.MIP.Manager.ApplicationMessageManager.SetCameraInViewHandler(Message message, FQID dest, FQID source)

at VideoOS.RemoteClient.Application.MIP.Manager.SCEnvironmentManager.ExecuteMessage(Message message, FQID destination, FQID sender, String logMessage)