Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ namespace CommunityToolkit.Maui.Core.Handlers;
/// </summary>
public partial class CameraViewHandler : ViewHandler<ICameraView, NativePlatformCameraPreviewView>, IDisposable
{
CancellationTokenSource? cts;
bool isDisposed;

/// <summary>
/// The currently defined mappings between properties on the <see cref="ICameraView"/> and
/// properties on the <see cref="NativePlatformCameraPreviewView"/>.
Expand Down Expand Up @@ -82,9 +85,29 @@ void Init(ICameraView view)
/// <inheritdoc/>
protected override async void ConnectHandler(NativePlatformCameraPreviewView platformView)
{
base.ConnectHandler(platformView);

await CameraManager.ConnectCamera(CancellationToken.None);
cts?.Cancel();
using var newCts = cts = new();
try
{
base.ConnectHandler(platformView);
await CameraManager.ConnectCamera(newCts.Token);
}
catch (OperationCanceledException) when (newCts.IsCancellationRequested)
{
// Catch and ignore the OperationCanceledException if it was caused by our own cancellation token,
// e.g. the handler is disconnected before the camera connection process completes.
}
catch (Exception)
{
DisconnectHandler(platformView);
}
Comment on lines +100 to +103
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ConnectHandler catches all exceptions and unconditionally calls DisconnectHandler(platformView). If the handler is already disconnecting/disposing, DisconnectHandler can throw (e.g., CameraManager field already set to null and the property throws), which defeats the goal of preventing crashes. Consider guarding this path (e.g., if cancellation was requested / handler is disposed / cameraManager is null, just return), and log the exception (Trace) for non-cancellation failures before disconnecting.

Copilot uses AI. Check for mistakes.
finally
{
if (cts == newCts)
{
cts = null;
}
}
}

/// <inheritdoc/>
Expand All @@ -103,11 +126,20 @@ protected override void DisconnectHandler(NativePlatformCameraPreviewView platfo
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool disposing)
{
if (isDisposed)
{
return;
}
if (disposing)
{
cts?.Cancel();
cts = null;

cameraManager?.Dispose();
cameraManager = null;
}

isDisposed = true;
}

#if WINDOWS
Expand Down
Loading