次の方法で共有


CA2016:CancellationToken パラメーターを 1 つのメソッドに転送する

プロパティ
型名 ForwardCancellationTokenToInvocations
ルール ID CA2016
Title CancellationToken パラメーターを 1 つのメソッドに転送する
[カテゴリ] 信頼性
修正が中断ありか中断なしか なし
.NET 8 では既定で有効 提案として

原因

この規則は、CancellationToken パラメーターを受け取ることができてもそれが渡されていないメソッドの呼び出しを検索し、親メソッドの CancellationToken をそれらに転送することを提案します。

規則の説明

このルールは、CancellationToken を最後のパラメーターとして受け取るメソッド定義を分析し、その本体で呼び出されたすべてのメソッドを分析します。 メソッド呼び出しのいずれかが最後のパラメーターとして CancellationToken を受け取ることができる場合、または CancellationToken を最後のパラメーターとして受け取るオーバーロードを使用している場合に、代わりにそのオプションを使用して、キャンセル通知をリッスンできるすべての操作に確実に反映させることを提案します。

注意

規則 CA2016 は、CancellationToken 型が使用可能なすべての .NET バージョンで使用できます。 該当するバージョンについては、CancellationToken の「適用対象」セクションを参照してください。

違反の修正方法

違反を手動で修正するか、Visual Studio で使用可能なコード修正プログラムを使用できます。 メソッド呼び出しの横に表示される電球をポイントし、推奨変更を選択します。

次の例は、2 つの変更の提案を示しています。

Rule CA2016 - Forward the CancellationToken parameter to methods that take one

キャンセルされた操作の通知が下位のメソッド呼び出しに転送される心配がない場合は、この規則の違反を抑制しても安全です。 また、明示的に C# の default (Visual Basic では Nothing) または None で渡すことで規則違反を抑制することもできます。

この規則によって、さまざまな違反を検出できます。 次の例は、規則が検出できるケースを示しています。

例 1

このメソッドは省略可能なトークン パラメーターを定義するため、この規則では c パラメーターを MyMethod から MyMethodWithDefault 呼び出しに転送することが推奨されます。

using System.Threading;

namespace ConsoleApp
{
    public static class MyTestClass
    {
        public static void MyMethodWithDefault(CancellationToken ct = default)
        {
        }

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithDefault();
        }
    }
}

解決策:

c パラメーターを転送します。

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithDefault(c);
        }

取り消し通知が下位の呼び出しに転送される心配がない場合は、次のいずれかの方法を使用できます。

明示的に default を渡します。

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithDefault(default);
        }

または、明示的に CancellationToken.None を渡します。

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithDefault(CancellationToken.None);
        }

例 2

このメソッドには CancellationToken パラメーターを受け取るオーバーロードがあるため、この規則では c パラメーターを MyMethod から MyMethodWithOverload 呼び出しに転送することが推奨されます。

using System.Threading;

namespace ConsoleApp
{
    public static class MyTestClass
    {
        public static void MyMethodWithOverload()
        {
        }

        public static void MyMethodWithOverload(CancellationToken ct = default)
        {
        }

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithOverload();
        }
    }
}

解決策:

c パラメーターを転送します。

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithOverload(c);
        }

取り消し通知が下位の呼び出しに転送される心配がない場合は、次のいずれかの方法を使用できます。

明示的に default を渡します。

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithOverload(default);
        }

または、明示的に CancellationToken.None を渡します。

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithOverload(CancellationToken.None);
        }

非違反の例

親メソッドの CancellationToken パラメーターが最後の位置にありません。

using System.Threading;

namespace ConsoleApp
{
    public static class MyTestClass
    {
        public static void MyMethodWithDefault(CancellationToken ct = default)
        {
        }

        public static void MyMethod(CancellationToken c, int lastParameter)
        {
            MyMethodWithDefault();
        }
    }
}

デフォルト メソッドの CancellationToken パラメーターが最後の位置にありません。

using System.Threading;

namespace ConsoleApp
{
    public static class MyTestClass
    {
        public static void MyMethodWithDefault(CancellationToken ct = default, int lastParameter = 0)
        {
        }

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithDefault();
        }
    }
}

オーバーロード メソッドの CancellationToken パラメーターが最後の位置にありません。

using System.Threading;

namespace ConsoleApp
{
    public static class MyTestClass
    {
        public static void MyMethodWithOverload(int lastParameter)
        {
        }
        public static void MyMethodWithOverload(CancellationToken ct, int lastParameter)
        {
        }

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithOverload();
        }
    }
}

親メソッドが複数の CancellationToken パラメーターを定義しています。

using System.Threading;

namespace ConsoleApp
{
    public static class MyTestClass
    {
        public static void MyMethodWithDefault(CancellationToken ct = default)
        {
        }

        public static void MyMethod(CancellationToken c1, CancellationToken c2)
        {
            MyMethodWithDefault();
        }
    }
}

デフォルトがあるメソッドが複数の CancellationToken パラメーターを定義しています。

using System.Threading;

namespace ConsoleApp
{
    public static class MyTestClass
    {
        public static void MyMethodWithDefault(CancellationToken c1 = default, CancellationToken c2 = default)
        {
        }

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithDefault();
        }
    }
}

メソッド オーバーロードが複数の CancellationToken パラメーターを定義しています。

using System.Threading;

namespace ConsoleApp
{
    public static class MyTestClass
    {
        public static void MyMethodWithOverload(CancellationToken c1, CancellationToken c2)
        {
        }

        public static void MyMethodWithOverload()
        {
        }

        public static void MyMethod(CancellationToken c)
        {
            MyMethodWithOverload();
        }
    }
}

警告を抑制する

単一の違反を抑制するだけの場合は、ソース ファイルにプリプロセッサ ディレクティブを追加して無効にしてから、規則をもう一度有効にします。

#pragma warning disable CA2016
// The code that's violating the rule is on this line.
#pragma warning restore CA2016

ファイル、フォルダー、またはプロジェクトの規則を無効にするには、構成ファイルでその重要度を none に設定します。

[*.{cs,vb}]
dotnet_diagnostic.CA2016.severity = none

詳細については、「コード分析の警告を抑制する方法」を参照してください。