次の方法で共有


IReliableConcurrentQueue<T>.EnqueueAsync メソッド

定義

値のエンキューをキューにステージングします。

public System.Threading.Tasks.Task EnqueueAsync (Microsoft.ServiceFabric.Data.ITransaction tx, T value, System.Threading.CancellationToken cancellationToken = default, TimeSpan? timeout = default);
abstract member EnqueueAsync : Microsoft.ServiceFabric.Data.ITransaction * 'T * System.Threading.CancellationToken * Nullable<TimeSpan> -> System.Threading.Tasks.Task
Public Function EnqueueAsync (tx As ITransaction, value As T, Optional cancellationToken As CancellationToken = Nothing, Optional timeout As Nullable(Of TimeSpan) = Nothing) As Task

パラメーター

tx
ITransaction

この操作を関連付けるトランザクション。

value
T

キューの末尾に追加する値。 参照型の場合は、値を null にできます。

cancellationToken
CancellationToken

キャンセル要求を監視するためのトークン。 既定値は、None です。

timeout
Nullable<TimeSpan>

TimeoutException をスローするまでの操作の完了を待機する時間。 既定値は null です。 null が渡された場合は、既定のタイムアウトが使用されます。

戻り値

非同期エンキュー操作を表すタスク。

例外

レプリカが で なくなりました。

レプリカは現在読み取り可能ではありません。

IReliableConcurrentQueue<T> ランタイムによって閉じられました。

レプリカに一時的な障害が発生しました。 新しいトランザクションで操作を再試行する

レプリカでは、上記で定義した型以外の再トライ不可能なエラーが発生しました。 例外をクリーンアップして再スローする

指定されたタイムアウト内に操作を完了できませんでした。 トランザクションを中止し、再試行するために新しいトランザクションを作成する必要があります。

tx が null です。

操作は を介して cancellationToken取り消されました。

トランザクションがシステムによって内部的に障害が発生しました。 新しいトランザクションで操作を再試行する

オブジェクトの現在の状態に対してメソッド呼び出しが無効な場合にスローされます。 たとえば、使用されているトランザクションは既に終了しています。ユーザーによってコミットまたは中止されています。 この例外がスローされた場合、トランザクションを使用するサービス コードにバグがある可能性が高くなります。

この例では、 を使用 EnqueueAsync(ITransaction, T, CancellationToken, Nullable<TimeSpan>) して再試行で値をエンキューする方法を示します。

protected override async Task RunAsync(CancellationToken cancellationToken)
{
    var concurrentQueue = await this.StateManager.GetOrAddAsync<IReliableConcurrentQueue<long>>(new Uri("fabric:/concurrentQueue"));

    while (true)
    {
        cancellationToken.ThrowIfCancellationRequested();

        try
        {
            using (var tx = this.StateManager.CreateTransaction())
            {
                await concurrentQueue.EnqueueAsync(tx, 12L, cancellationToken);
                await tx.CommitAsync();

                return;
            }
        }
        catch (TransactionFaultedException e)
        {
            // This indicates that the transaction was internally faulted by the system. One possible cause for this is that the transaction was long running
            // and blocked a checkpoint. Increasing the "ReliableStateManagerReplicatorSettings.CheckpointThresholdInMB" will help reduce the chances of running into this exception
            Console.WriteLine("Transaction was internally faulted, retrying the transaction: " + e);
        }
        catch (FabricNotPrimaryException e)
        {
            // Gracefully exit RunAsync as the new primary should have RunAsync invoked on it and continue work.
            // If instead enqueue was being executed as part of a client request, the client would be signaled to re-resolve.
            Console.WriteLine("Replica is not primary, exiting RunAsync: " + e);
            return;
        }
        catch (FabricNotReadableException e)
        {
            // Retry until the queue is readable or a different exception is thrown.
            Console.WriteLine("Queue is not readable, retrying the transaction: " + e);
        }
        catch (FabricObjectClosedException e)
        {
            // Gracefully exit RunAsync as this is happening due to replica close.
            // If instead enqueue was being executed as part of a client request, the client would be signaled to re-resolve.
            Console.WriteLine("Replica is closing, exiting RunAsync: " + e);
            return;
        }
        catch (TimeoutException e)
        {
            Console.WriteLine("Encountered TimeoutException during EnqueueAsync, retrying the transaction: " + e);
        }
        catch (FabricTransientException e)
        {
            // Retry until the queue is writable or a different exception is thrown.
            Console.WriteLine("Queue is currently not writable, retrying the transaction: " + e);
        }

        // Delay and retry.
        await Task.Delay(TimeSpan.FromMilliseconds(100), cancellationToken);
    }
}

注釈

TryDequeueAsync(ITransaction, CancellationToken, Nullable<TimeSpan>)操作は、まだコミットされていない値をEnqueueAsync(ITransaction, T, CancellationToken, Nullable<TimeSpan>)返すことはできません。 これには、値がエンキューされたトランザクションが含まれます。結果として、 IReliableConcurrentQueue<T> は読み取り-Your-Writes をサポートしていません。

適用対象