Skip to content
Merged
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
66 changes: 22 additions & 44 deletions WinSyncScroll/ViewModels/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -545,29 +545,16 @@ public void HandleWindowClosing()
}
}

public void Dispose()
private void WaitForTaskCompletion(Task? task, string taskName, TimeSpan timeout)
{
AppState = AppState.NotRunning;
try
{
_cancellationTokenSource.Cancel();
}
catch (Exception e)
{
_logger.LogError(e, "Error cancelling the cancellation token source");
}

// Wait for tasks to complete before disposing resources
// Using Task.Wait in Dispose is acceptable as this is a shutdown scenario
// and we need to ensure tasks complete before disposing underlying resources
#pragma warning disable VSTHRD002 // Synchronously waiting is acceptable in Dispose method
#pragma warning disable VSTHRD002 // Synchronously waiting is acceptable in shutdown scenarios
try
{
if (_updateMouseHookRectsLoopTask is not null
&& !_updateMouseHookRectsLoopTask.IsCompleted
&& !_updateMouseHookRectsLoopTask.Wait(TimeSpan.FromSeconds(5)))
if (task is not null
&& !task.IsCompleted
&& !task.Wait(timeout))
{
_logger.LogWarning("Update mouse hook rects loop task did not complete within timeout");
_logger.LogWarning("{TaskName} did not complete within timeout", taskName);
}
}
catch (AggregateException ae)
Expand All @@ -576,47 +563,38 @@ public void Dispose()
{
if (ex is OperationCanceledException)
{
_logger.LogDebug("Update mouse hook rects loop was cancelled");
_logger.LogDebug("{TaskName} was cancelled", taskName);
return true;
}

_logger.LogError(ex, "Error waiting for update mouse hook rects loop task");
_logger.LogError(ex, "Error waiting for {TaskName} to complete", taskName);
return true;
});
}
catch (Exception e)
{
_logger.LogError(e, "Error disposing update mouse hook rects loop task");
_logger.LogError(e, "Error waiting for {TaskName} to complete", taskName);
}
#pragma warning restore VSTHRD002
}

public void Dispose()
{
AppState = AppState.NotRunning;
try
{
if (_mouseEventProcessingLoopTask is not null
&& !_mouseEventProcessingLoopTask.IsCompleted
&& !_mouseEventProcessingLoopTask.Wait(TimeSpan.FromSeconds(5)))
{
_logger.LogWarning("Mouse event processing loop task did not complete within timeout");
}
}
catch (AggregateException ae)
{
ae.Handle(ex =>
{
if (ex is OperationCanceledException)
{
_logger.LogDebug("Mouse event processing loop was cancelled");
return true;
}

_logger.LogError(ex, "Error waiting for mouse event processing loop task");
return true;
});
_cancellationTokenSource.Cancel();
}
catch (Exception e)
{
_logger.LogError(e, "Error disposing mouse event processing loop task");
_logger.LogError(e, "Error cancelling the cancellation token source");
}
#pragma warning restore VSTHRD002

// Wait for tasks to complete before disposing resources
// Using Task.Wait in Dispose is acceptable as this is a shutdown scenario
// and we need to ensure tasks complete before disposing underlying resources
WaitForTaskCompletion(_updateMouseHookRectsLoopTask, "Update mouse hook rects loop task", TimeSpan.FromSeconds(5));
WaitForTaskCompletion(_mouseEventProcessingLoopTask, "Mouse event processing loop task", TimeSpan.FromSeconds(5));

// Dispose tasks after they have completed
_updateMouseHookRectsLoopTask?.Dispose();
Expand Down