Open sandboxFocusImprove this doc

THR006: Method Cannot Be Executed in the Background

Severity Error
Reported by PostSharp.Patterns.Threading
Message Method "<Method>" cannot be enhanced with the [Background] aspect. This aspect can only be applied to methods that have no ref, out or in parameters and whose return type is void, Task or Task<T>.

Cause

The BackgroundAttribute aspect executes a method in the thread pool, or in a new thread when IsLongRunning is true. The caller does not wait for the method to complete, so it cannot receive a return value or the values of ref and out parameters, unless the method returns a task that the caller can await.

PostSharp therefore reports THR006 when a method with the aspect:

  • has a return type that is neither void nor Task or Task<T>, for example int, string or ValueTask<T>;
  • has a ref, out or in parameter.

In the following example, the GenerateReport method returns a string.

using System;
using System.Threading;
using System.Threading.Tasks;
using PostSharp.Patterns.Threading;

namespace Errors.THR006_Error;

public class ReportService
{
    // The caller needs the report before the background thread has generated it.
    [Background]
    public string GenerateReport( int year )
    {
        return $"Report {year}, generated in the thread pool: {Thread.CurrentThread.IsThreadPoolThread}";
    }
}

public static class Program
{
    public static void Main()
    {
        var service = new ReportService();
        Console.WriteLine( service.GenerateReport( 2026 ) );
    }
}
error THR006: THR006_Error.cs(12,19): Method "Errors.THR006_Error.ReportService.GenerateReport(System.Int32)" cannot be enhanced with the [Background] aspect. This aspect can only be applied to methods that have no ref, out or in parameters and whose return type is void, Task or Task<T>.

Resolution

  • When the caller needs the result of the method, make the method async and return a Task<T>. The caller awaits the task, which completes when the method completes in the background.
  • When the caller does not need a result, make the method return void or Task.
  • Replace ref, out and in parameters with the return value of the task, or with ordinary parameters.

In the following example, the method returns a Task<string>, which Main awaits.

using System;
using System.Threading;
using System.Threading.Tasks;
using PostSharp.Patterns.Threading;

namespace Errors.THR006_Fixed;

public class ReportService
{
    // The method returns a task, which completes when the background thread has generated the report.
    [Background]
    public async Task<string> GenerateReport( int year )
    {
        await Task.Yield();

        return $"Report {year}, generated in the thread pool: {Thread.CurrentThread.IsThreadPoolThread}";
    }
}

public static class Program
{
    public static async Task Main()
    {
        var service = new ReportService();
        Console.WriteLine( await service.GenerateReport( 2026 ) );
    }
}
Report 2026, generated in the thread pool: True

See Also

Reference

BackgroundAttribute

Other Resources

Dispatching a Method to Background