diff --git a/src/Sentry.Profiling/SamplingTransactionProfilerFactory.cs b/src/Sentry.Profiling/SamplingTransactionProfilerFactory.cs
index 5f0d54453d..386fd1f4f2 100644
--- a/src/Sentry.Profiling/SamplingTransactionProfilerFactory.cs
+++ b/src/Sentry.Profiling/SamplingTransactionProfilerFactory.cs
@@ -1,3 +1,4 @@
+using Sentry.Ben.BlockingDetector;
using Sentry.Extensibility;
using Sentry.Internal;
@@ -27,16 +28,19 @@ public SamplingTransactionProfilerFactory(SentryOptions options, TimeSpan startu
{
_options = options;
- _sessionTask = Task.Run(async () =>
+ using (new SuppressBlockingDetection())
{
- // This can block up to 30 seconds. The timeout is out of our hands.
- var session = SampleProfilerSession.StartNew(options.DiagnosticLogger);
+ _sessionTask = Task.Run(async () =>
+ {
+ // This can block up to 30 seconds. The timeout is out of our hands.
+ var session = SampleProfilerSession.StartNew(options.DiagnosticLogger);
- // This can block indefinitely.
- await session.WaitForFirstEventAsync().ConfigureAwait(false);
+ // This can block indefinitely.
+ await session.WaitForFirstEventAsync().ConfigureAwait(false);
- return session;
- });
+ return session;
+ });
+ }
Debug.Assert(TimeSpan.FromSeconds(0) == TimeSpan.Zero);
if (startupTimeout != TimeSpan.Zero && !_sessionTask.Wait(startupTimeout))
diff --git a/src/Sentry/Internal/BackgroundWorker.cs b/src/Sentry/Internal/BackgroundWorker.cs
index d747922d5a..f7a283f3ed 100644
--- a/src/Sentry/Internal/BackgroundWorker.cs
+++ b/src/Sentry/Internal/BackgroundWorker.cs
@@ -1,3 +1,4 @@
+using Sentry.Ben.BlockingDetector;
using Sentry.Extensibility;
using Sentry.Internal.Extensions;
using Sentry.Internal.Http;
@@ -37,7 +38,10 @@ public BackgroundWorker(
_queuedEnvelopeSemaphore = new SemaphoreSlim(0, _maxItems);
options.LogDebug("Starting BackgroundWorker.");
- WorkerTask = Task.Run(DoWorkAsync);
+ using (new SuppressBlockingDetection())
+ {
+ WorkerTask = Task.Run(DoWorkAsync);
+ }
}
///
diff --git a/src/Sentry/Internal/GarbageCollectionMonitor.cs b/src/Sentry/Internal/GarbageCollectionMonitor.cs
index a17486b8fd..825f628172 100644
--- a/src/Sentry/Internal/GarbageCollectionMonitor.cs
+++ b/src/Sentry/Internal/GarbageCollectionMonitor.cs
@@ -1,3 +1,4 @@
+using Sentry.Ben.BlockingDetector;
using Sentry.Extensibility;
namespace Sentry.Internal;
@@ -10,8 +11,13 @@ internal sealed class GarbageCollectionMonitor
private const int MaxGenerationThreshold = 10;
private const int LargeObjectHeapThreshold = 10;
- public static Task Start(Action onGarbageCollected, CancellationToken cancellationToken, IGCImplementation? gc = null) =>
- Task.Run(() => MonitorGarbageCollection(onGarbageCollected, cancellationToken, gc), cancellationToken);
+ public static Task Start(Action onGarbageCollected, CancellationToken cancellationToken, IGCImplementation? gc = null)
+ {
+ using (new SuppressBlockingDetection())
+ {
+ return Task.Run(() => MonitorGarbageCollection(onGarbageCollected, cancellationToken, gc), cancellationToken);
+ }
+ }
private static void MonitorGarbageCollection(Action onGarbageCollected, CancellationToken cancellationToken, IGCImplementation? gc = null)
{
diff --git a/src/Sentry/Internal/Http/CachingTransport.cs b/src/Sentry/Internal/Http/CachingTransport.cs
index b5ed2cb34a..039226d7d0 100644
--- a/src/Sentry/Internal/Http/CachingTransport.cs
+++ b/src/Sentry/Internal/Http/CachingTransport.cs
@@ -1,3 +1,5 @@
+using System.Text.Json;
+using Sentry.Ben.BlockingDetector;
using Sentry.Extensibility;
using Sentry.Internal.Extensions;
using Sentry.Protocol.Envelopes;
@@ -98,7 +100,10 @@ private void Initialize(bool startWorker)
if (startWorker)
{
_options.LogDebug("Starting CachingTransport worker.");
- _worker = Task.Run(CachedTransportBackgroundTaskAsync);
+ using (new SuppressBlockingDetection())
+ {
+ _worker = Task.Run(CachedTransportBackgroundTaskAsync);
+ }
}
else
{
diff --git a/src/Sentry/Internal/ProcessInfo.cs b/src/Sentry/Internal/ProcessInfo.cs
index 414c93e394..65d3bc13b8 100644
--- a/src/Sentry/Internal/ProcessInfo.cs
+++ b/src/Sentry/Internal/ProcessInfo.cs
@@ -1,3 +1,4 @@
+using Sentry.Ben.BlockingDetector;
using Sentry.Extensibility;
namespace Sentry.Internal;
@@ -95,20 +96,23 @@ internal ProcessInfo(
// This method will give a better precision to the StartupTime at a cost
// of calling Process.GetCurrentProcess, on a thread pool thread.
var preciseStartupTimeFunc = findPreciseStartupTime ?? GetStartupTime;
- PreciseAppStartupTask = Task.Run(() =>
+ using (new SuppressBlockingDetection())
{
- try
+ PreciseAppStartupTask = Task.Run(() =>
{
- StartupTime = preciseStartupTimeFunc();
- }
- catch (Exception e)
- {
- options.LogError(e, "Failure getting precise App startup time.");
- //Ignore any exception and stay with the less-precise DateTime.UtcNow value.
- }
- }).ContinueWith(_ =>
- // Let the actual task get collected
- PreciseAppStartupTask = Task.CompletedTask);
+ try
+ {
+ StartupTime = preciseStartupTimeFunc();
+ }
+ catch (Exception e)
+ {
+ options.LogError(e, "Failure getting precise App startup time.");
+ //Ignore any exception and stay with the less-precise DateTime.UtcNow value.
+ }
+ }).ContinueWith(_ =>
+ // Let the actual task get collected
+ PreciseAppStartupTask = Task.CompletedTask);
+ }
#endif
}
}
diff --git a/test/Sentry.Tests/Internals/BackgroundWorkerTests.cs b/test/Sentry.Tests/Internals/BackgroundWorkerTests.cs
index d506a179e6..b52b468a76 100644
--- a/test/Sentry.Tests/Internals/BackgroundWorkerTests.cs
+++ b/test/Sentry.Tests/Internals/BackgroundWorkerTests.cs
@@ -1,4 +1,5 @@
using System.IO.Abstractions.TestingHelpers;
+using Sentry.Ben.BlockingDetector;
using Sentry.Internal.Http;
using BackgroundWorker = Sentry.Internal.BackgroundWorker;
@@ -521,4 +522,38 @@ public async Task FlushAsync_Calls_CachingTransport_FlushAsync()
_fixture.Logger.Received(1)
.Log(SentryLevel.Debug, "CachingTransport received request to flush the cache.");
}
+
+ [Fact]
+ public void Ctor_SuppressesBlockingDetection_WhenCreatingTask()
+ {
+ // Arrange
+ var listenerState = Substitute.For();
+ var monitor = Substitute.For();
+ var context = new DetectBlockingSynchronizationContext(monitor);
+
+ // Mock the current sync context to our test context
+ SynchronizationContext.SetSynchronizationContext(context);
+
+ // Mock the TaskBlockingListener to return our test state
+ var originalDefaultState = TaskBlockingListener.DefaultState;
+ TaskBlockingListener.DefaultState = listenerState;
+
+ try
+ {
+ // Act
+ using var sut = _fixture.GetSut();
+
+ // Assert
+ // Verify that suppression was called when creating the task
+ listenerState.Received(1).Suppress();
+ // Verify that restoration was called when exiting the using block
+ listenerState.Received(1).Restore();
+ }
+ finally
+ {
+ // Cleanup
+ TaskBlockingListener.DefaultState = originalDefaultState;
+ SynchronizationContext.SetSynchronizationContext(null);
+ }
+ }
}