Compartir a través de


IReliableConcurrentQueue<T>.TryDequeueAsync Método

Definición

Poner provisionalmente en cola un valor de la cola. Si la cola está vacía, la operación de puesta en cola esperará a que un elemento esté disponible.

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

Parámetros

tx
ITransaction

Transacción con la que asociar esta operación.

cancellationToken
CancellationToken

Token para supervisar solicitudes de cancelación. El valor predeterminado es None.

timeout
Nullable<TimeSpan>

Cantidad de tiempo que se va a esperar a que se complete la operación. El valor predeterminado es null. Si se pasa null, se usará un tiempo de espera predeterminado.

Devoluciones

Tarea que representa la operación de puesta en cola asincrónica. El resultado de la tarea es conditionalValue de tipo T. Si un valor se desquetó dentro del tiempo determinado, devuelva un ConditionalValue con HasValue como false, de lo contrario devuelve un ConditionalValue con HasValue como true y el valor como el elemento desqueued del tipo T.

Excepciones

La réplica ya no está en .

Actualmente, la réplica no es legible.

El IReliableConcurrentQueue<T> tiempo de ejecución cerró .

La réplica vio un error transitorio. Reintentar la operación en una nueva transacción

La réplica vio un error no reintenible distinto de los tipos definidos anteriormente. Limpiar y volver a iniciar la excepción

No se pudo completar la operación dentro del tiempo de espera especificado. Se debe anular la transacción y se debe crear una nueva transacción para reintentar.

tx es null. No controle esta excepción.

La operación se canceló a través de cancellationToken.

El sistema ha producido un error interno en la transacción. Reintentar la operación en una nueva transacción

Se produce cuando una llamada de método no es válida para el estado actual del objeto. Por ejemplo, la transacción usada ya ha finalizado: el usuario la ha confirmado o anulado. Si se produce esta excepción, es muy probable que haya un error en el código de servicio del uso de transacciones.

Ejemplos

En este ejemplo se muestra cómo quitar la cola y registrar infinitamente con reintentos, hasta que se cancele el token de cancelación.

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

    // Assumption: values are being enqueued by another source (e.g. the communication listener).
    while (true)
    {
        cancellationToken.ThrowIfCancellationRequested();

        try
        {
            using (var tx = this.StateManager.CreateTransaction())
            {
                var dequeueOutput = await concurrentQueue.TryDequeueAsync(tx, cancellationToken, TimeSpan.FromMilliseconds(100));
                await tx.CommitAsync();

                if (dequeueOutput.HasValue)
                {
                    Console.WriteLine("Dequeue # " + dequeueOutput);
                }
                else
                {
                    Console.WriteLine("Could not dequeue in the given time");
                }
            }
        }
        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 dequeue 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 dequeue 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 DequeueAsync, 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);
    }
}

Comentarios

Aunque TryDequeueAsync(ITransaction, CancellationToken, Nullable<TimeSpan>) solo puede devolver valores para los que se confirmó el correspondiente EnqueueAsync(ITransaction, T, CancellationToken, Nullable<TimeSpan>) , TryDequeueAsync(ITransaction, CancellationToken, Nullable<TimeSpan>) las operaciones no están aisladas entre sí. Una vez que una transacción ha desqueuado un valor, otras transacciones no pueden quitarla de la cola, pero no se bloquean para poner en cola otros valores.

Cuando se anula una transacción o transacción, incluidas una o varias TryDequeueAsync(ITransaction, CancellationToken, Nullable<TimeSpan>) operaciones, los valores puestos en cola se volverán a agregar al encabezado de la cola en un orden arbitrario. Esto garantizará que estos valores se vuelvan a poner en cola pronto, lo que mejorará la equidad de la estructura de datos, pero sin aplicar una ordenación estricta (lo que requeriría reducir la simultaneidad permitida, como en IReliableQueue<T>).

Se aplica a