Compartir a través de


Operaciones en segundo plano (versión preliminar)

[Este artículo es documentación preliminar y está sujeto a modificaciones].

Use operaciones en segundo plano para enviar solicitudes que Dataverse procesa de forma asincrónica. Las operaciones en segundo plano son útiles cuando no desea mantener una conexión mientras se ejecuta una solicitud.

Cuando se completa una operación en segundo plano, puede recibir una notificación de dos maneras:

Puede recuperar el resultado de una operación en segundo plano de dos maneras:

Para ejecutar una solicitud en segundo plano, la operación debe definirse como una API personalizada. Obtenga información sobre cómo crear y usar API personalizadas y recuperar datos sobre las API personalizadas.

Las API personalizadas usan complementos para realizar operaciones de datos. Al igual que todos los complementos de Dataverse, estos complementos tienen un tiempo de espera de ejecución de dos minutos. El envío de la solicitud de forma asincrónica no proporciona más tiempo de ejecución.

Privilegios requeridos

Para realizar una operación en segundo plano, el usuario iniciador debe tener acceso de lectura y escritura a la backgroundoperations tabla. Asigne los prvReadbackgroundoperation privilegios y prvWritebackgroundoperation para conceder este acceso.

Obtenga información sobre cómo editar un rol de seguridad.

Solicitud de procesamiento asincrónico

Puede ejecutar solicitudes asincrónicas en segundo plano mediante el SDK para .NET o la API web de Dataverse.

En los ejemplos de este artículo se usa una API personalizada denominada sample_ExportDataUsingFetchXmlToAnnotation. Esta API personalizada se describe en Sample: ExportDataUsingFetchXmlToAnnotation custom API.

Utilice el ExecuteBackgroundOperation mensaje.

El SDK no tiene ExecuteBackgroundOperation clases de solicitud y respuesta. Hasta que se agreguen estas clases, use las clases Base OrganizationRequest y OrganizationResponse , tal como se describe en Uso de mensajes con el SDK para .NET.

En la tabla siguiente se describen los parámetros de entrada del ExecuteBackgroundOperation mensaje.

Nombre Tipo Description
Request OrganizationRequest (Obligatorio) Contiene la solicitud que desea haber procesado de forma asincrónica. El mensaje de Dataverse para la solicitud debe implementarse como una API personalizada.
CallbackUri cuerda / cadena (Opcional) Dataverse envía una solicitud HTTP POST a esta dirección URL cuando se completa la operación.

En la tabla siguiente se describen los parámetros de salida del ExecuteBackgroundOperation mensaje.

Nombre Tipo Description
BackgroundOperationId GUID Identifica la fila de la tabla de operaciones en segundo plano que puede usar para supervisar o cancelar el procesamiento de la solicitud.
Location cuerda / cadena Identifica la dirección URL del recurso del monitor de estado que puede usar para recuperar el estado de la solicitud o cancelarla.

El siguiente método estático usa ExecuteBackgroundOperation con la sample_ExportDataUsingFetchXmlToAnnotation API personalizada.

static void SendRequestAsynchronously(IOrganizationService service)
{
    //Create a request for message defined as a custom API to run in the background
    var asyncRequest = new OrganizationRequest("sample_ExportDataUsingFetchXmlToAnnotation")
    {
        Parameters =
        {
            {"FetchXml",  @"<fetch>
                                <entity name='account'>
                                    <attribute name='accountid'/>
                                    <attribute name='name'/>  
                                </entity>
                            </fetch>" }
        }
    };

    //Create a request to execute the message in the background
    var request = new OrganizationRequest("ExecuteBackgroundOperation")
    {
        Parameters =
        {
            {"Request", asyncRequest }
        }
    };

    //Execute the background operation request
    var response = service.Execute(request);

    Console.WriteLine($"BackgroundOperationId: {response["BackgroundOperationId"]}");
    Console.WriteLine($"Location: {response["Location"]}");
}

Salida:

BackgroundOperationId: <backgroundoperationid value>
Location: [Organization URI]/api/backgroundoperation/<backgroundoperationid value>

Obtenga más información sobre la interfaz IOrganizationService y cómo usar mensajes con el SDK para .NET.

Administración de operaciones en segundo plano

Al enviar una solicitud que se va a procesar en segundo plano, la respuesta incluye dos valores que representan métodos diferentes que puede usar para supervisar o cancelar operaciones en segundo plano.

Consultar la tabla de operaciones en segundo plano o el recurso de supervisión de estado para comprobar las solicitudes se conoce normalmente como sondeo de estado. Se recomienda evitar sondeos excesivos porque puede afectar negativamente al rendimiento. Si es necesario, se recomienda sondear en un intervalo de un minuto o más.

Tabla de operaciones en segundo plano

La tabla de operaciones en segundo plano contiene información sobre las solicitudes para procesar de forma asincrónica. Esta tabla tiene el nombre backgroundoperation lógico y el nombre backgroundoperationsdel conjunto de entidades . Obtenga información sobre backgroundoperation EntityType.

En la tabla siguiente se describen las columnas que puede usar para administrar el estado de las operaciones en segundo plano.

Nombre
Nombre del esquema
Nombre lógico
Tipo Description
Operación en segundo plano
BackgroundOperationId
backgroundoperationid
Uniqueidentifier La clave principal
Estado
StateCode
backgroundoperationstatecode
Lista de selección Estado de la operación en segundo plano

Options:
- Valor: 0, Etiqueta: Listo
- Valor: 2, Etiqueta: Bloqueado
- Valor: 3, Etiqueta: Completado
Razón para el estado
StatusCode
backgroundoperationstatuscode
Lista de selección Estado de la operación en segundo plano

Options:
- Valor: 0, etiqueta: esperando recursos (estado:listo)
- Valor: , etiqueta: 20en curso (estado:bloqueado)
- Valor: , Etiqueta: 22Cancelación (Estado:Bloqueado)
- Valor: 30, Etiqueta: Exitoso (Estado:Completado)
- Valor: 31, Etiqueta: Error (Estado:Completado)
- Valor: 32, Etiqueta: Cancelada (Estado:Completado)
Nombre
Name
name
String UniqueName de la API personalizada que se usa para la operación en segundo plano
DisplayName (Nombre para mostrar)
DisplayName
displayname
String DisplayName de la API personalizada utilizada para la operación en segundo plano
Parámetros de entrada
InputParameters
inputparameters
Memorándum Parámetros de entrada proporcionados para iniciar la operación en segundo plano

Esta cadena es una matriz serializada json de Key y Value.
Parámetros de salida
OutputParameters
outputparameters
Memorándum La respuesta de la operación en segundo plano

Esta cadena es una matriz serializada json de Key y Value.
Hora de comienzo
StartTime
starttime
DateTime Cuando se inició la ejecución de la operación en segundo plano
Hora de finalización
EndTime
endtime
DateTime Cuando la operación en segundo plano finaliza la ejecución
Recuento de reintentos
RetryCount
retrycount
Integer Número de veces que se reintentó la operación en segundo plano.
Código de error
ErrorCode
errorcode
Integer Código de error si se produce un error en la operación en segundo plano

Si el error procede de Dataverse, tiene un valor entero que corresponde a uno de los códigos enumerados en códigos de error del servicio web. Si el error no procede de Dataverse, el valor se establece en cero.
Mensaje de error
ErrorMessage
errormessage
Memorándum Mensaje de error si se produce un error en la operación en segundo plano
Ejecutar como
RunAs
runas
String El systemuserid del systemuser utilizado para ejecutar la operación en segundo plano
Creadas el
CreatedOn
createdon
DateTime Cuando se creó el registro
Período de vida
TTLInSeconds
ttlinseconds
Integer Tiempo de vida en segundos, después del cual el registro se elimina automáticamente; el valor predeterminado es 90 días.

Sondee la tabla de operaciones en segundo plano

Asegúrese de incluir estas columnas en la consulta:

  • name
  • backgroundoperationstatecode
  • backgroundoperationstatuscode
  • outputparameters
  • errorcode
  • errormessage

La forma de sondear la tabla depende de si usa el SDK o la API web.

static void PollBackgroundOperationRequest(IOrganizationService service, Guid backgroundOperationId)
{
    // List of columns that will help to get status, output and error details if any
    var columnSet = new ColumnSet(
        "name",
        "backgroundoperationstatecode",
        "backgroundoperationstatuscode",
        "outputparameters",
        "errorcode",
        "errormessage");

    try
    {
        // Get the entity with all the required columns
        var backgroundOperation = service.Retrieve("backgroundoperation", backgroundOperationId, columnSet);

        Console.WriteLine($"Name: {backgroundOperation["name"]}");
        Console.WriteLine($"State Code: {backgroundOperation.FormattedValues["backgroundoperationstatecode"]}");
        Console.WriteLine($"Status Code: {backgroundOperation.FormattedValues["backgroundoperationstatuscode"]}");
        Console.WriteLine($"Output Parameters:");

        // Deserialize the Output Parameters into KeyValuePair<string, string>
        List<KeyValuePair<string, string>>? output = 
            System.Text.Json.JsonSerializer
            .Deserialize<List<KeyValuePair<string, string>>>((string)backgroundOperation["outputparameters"]);

        output.ForEach(x => {
            Console.WriteLine($"\t{x.Key}: {x.Value}");
        });

        Console.WriteLine($"Error Code: {backgroundOperation.GetAttributeValue<string>("errorcode")}");
        Console.WriteLine($"Error Message: {backgroundOperation.GetAttributeValue<string>("errormessage")}");
    }
    // Catch Dataverse errors
    catch (FaultException<OrganizationServiceFault> ex)
    {
        Console.WriteLine($"ErrorCode:{ex.Detail.ErrorCode}");
        Console.WriteLine($"Message:{ex.Detail.Message}");
    }
    // Catch other errors
    catch (Exception error)
    {
        Console.WriteLine($"Some other error occurred: '{error.Message}'");
    }
}

Salida pendiente:

Name: sample_ExportDataUsingFetchXmlToAnnotation
State Code: Locked
Status Code:  In Progress
Output Parameters:  
Error Code:  
Error Message:  

Salida completa:

Name: sample_ExportDataUsingFetchXmlToAnnotation
State Code: Completed
Status Code:  Succeeded
Output Parameters:
        AnnotationId: {value}
Error Code:  
Error Message:  

Salida de error:

Name: sample_ExportDataUsingFetchXmlToAnnotation
State Code: Completed
Status Code:  Failed
Output Parameters: 
Error Code:  -2147187707
Error Message:  Access is denied.

Si la plataforma produce el error, tiene un valor entero que corresponde a uno de los códigos enumerados en los códigos de error del servicio web. Si la plataforma no produce el error, su valor se establece en cero.

No se encontró el identificador:

ErrorCode:-2147185406
Message:The HTTP status code of the response was not expected (404).

Status: 404
Response:
{"error":{"message":"Could not find item '110eaa68-db17-4115-ad74-d185823fc089'.","details":[{"message":"\r\nErrors : [\r\n  \"Resource Not Found. Learn more: https://aka.ms/cosmosdb-tsg-not-found\"\r\n]\r\n"}]}}

Sondeo del recurso de supervisión de estado

Puede sondear el recurso del monitor de estado con una solicitud GET, que devuelve el estado de la operación en segundo plano. Si se completa la operación, proporciona la salida de la API personalizada. Si se produjo un error durante la ejecución, recibirá un mensaje de error y un código.

Envíe una solicitud a la URL del recurso del monitor de estado que se devolvió con el encabezado Location de respuesta de la solicitud original.

Solicitud:

GET [Organization URI]/api/backgroundoperation/{backgroundoperationid}
Content-Type: application/json  

Respuesta:

HTTP/1.1 200 OK
Content-Type: application/json

{
  backgroundOperationErrorCode: {INT},
  backgroundOperationErrorMessage: {string},
  backgroundOperationStateCode: {INT},
  backgroundOperationStatusCode: {INT},
  outputParam1: {value},
  outputParam2: {value},
  outputParam3: {value},
}

backgroundOperationErrorCode y backgroundOperationErrorMessage valores solo se incluyen en caso de error. Los parámetros de salida solo se incluyen cuando la operación se completa correctamente.

Las etiquetas no están disponibles en el recurso de monitorización de estado.

Recepción de la notificación del resultado

Para recibir una notificación cuando finalice una operación en segundo plano, puede incluir una URL de devolución de llamada con su solicitud o suscribirse al evento OnBackgroundOperationComplete.

Solicitar una llamada de vuelta

Puede especificar una URL en la solicitud para recibir una notificación cuando se complete la operación. Dataverse usa esta dirección URL para enviar una solicitud POST con la carga siguiente:

{
    "location": "< status monitor resource URL >",
    "backgroundOperationId": "{GUID}",
    "backgroundOperationStateCode": {INT},
    "backgroundOperationStatusCode": {INT},
    "backgroundOperationErrorCode": {INT},
    "backgroundOperationErrorMessage": {string},
}

backgroundOperationErrorCode y backgroundOperationErrorMessage solo se incluyen cuando se produce un error.

La carga de devolución de llamada no incluye ningún parámetro de salida. El sitio que recibe el callback debe enviar una solicitud GET autenticada usando la URL del recurso del monitor de estado para obtener resultados.

Si la dirección URL requiere autenticación, debe ser una dirección URL de firma de acceso compartido (SAS) autoadministrada. No es posible incluir más encabezados para incluir claves de API o tokens para la autenticación.

Es posible que desee utilizar un sitio como webhook.site para probar la URL de devolución de llamada.

La forma en que solicita una devolución de llamada depende de si está utilizando el SDK o la API web. En los ejemplos siguientes se envía una solicitud mediante un webhook a webhook.site para realizar pruebas.

Con el SDK, establezca el ExecuteBackgroundOperation.CallbackUri parámetro en la dirección URL para enviar la solicitud.

static void SendRequestAsynchronouslyWithCallback(IOrganizationService service)
{
    //Create a request for message defined as a custom API to run in the background
    var asyncRequest = new OrganizationRequest("sample_ExportDataUsingFetchXmlToAnnotation")
    {
        Parameters =
        {
            {"FetchXml",  @"<fetch>
                                <entity name='account'>
                                    <attribute name='accountid'/>
                                    <attribute name='name'/>  
                                </entity>
                            </fetch>" }
        }
    };

    //Create a request to execute the message in the background
    var request = new OrganizationRequest("ExecuteBackgroundOperation")
    {
        Parameters =
        {
            {"Request", asyncRequest },
            // Request a callback
            {"CallbackUri", "https://webhook.site/<id>" }
        }
    };

    //Execute the background operation request
    var response = service.Execute(request);

    Console.WriteLine($"BackgroundOperationId: {response["BackgroundOperationId"]}");
    Console.WriteLine($"Location: {response["Location"]}");
}

Suscríbase al evento OnBackgroundOperationComplete

Otra manera de recibir una notificación cuando se completa una operación en segundo plano es registrar un evento en el mensaje OnBackgroundOperationComplete. Este mensaje es una API personalizada que solo permite registros de pasos asincrónicos. Es un ejemplo del tipo de mensajes creados mediante una API personalizada para representar eventos empresariales.

Como sugiere el nombre, el evento OnBackgroundOperationComplete se produce cada vez que se completa una operación en segundo plano. Al registrar un paso asincrónico en este evento, puede realizar cualquier tipo de lógica que desee en un complemento o reenviar los datos a los servicios de Azure o a un webhook. Aprende más:

En las tablas siguientes se describen los parámetros de entrada y salida del OnBackgroundOperationComplete mensaje.

Parámetros de entrada:

Nombre Tipo Description
PayloadType Integer Qué tipo de respuesta se envía al URI de devolución de llamada cuando se completa la operación en segundo plano; siempre cero para operaciones en segundo plano

Este campo es interno y no debe actualizarse.
LocationUrl String Dirección URL de ubicación
BackgroundOperationId GUID Identificador de la operación en segundo plano

Parámetros de salida:

Nombre Tipo Description
OperationName String Nombre de la operación
BackgroundOperationStateCode Integer Código de estado de la operación en segundo plano
BackgroundOperationStatusCode Integer Código de estado de la operación en segundo plano

Configure el OnBackgroundOperationComplete mensaje como se muestra en las instrucciones para registrar un complemento. Asegúrese de establecer el nombre del mensaje como OnBackgroundOperationComplete. Establezca Eliminación automática en true para que el registro de trabajo del sistema (AsyncOperation) se quite automáticamente.

Cancelar las operaciones en segundo plano

Puede cancelar una operación en segundo plano que inició si no se ha iniciado.

  • Si la operación no se ha iniciado, Dataverse no la ejecuta.
  • Si se ha iniciado la operación, Dataverse no lo detiene.
  • Si se produce un error durante la ejecución de una operación en segundo plano que canceló, Dataverse no lo reintenta.
  • Si la operación ya se ha completado, obtendrá el siguiente error: Canceling background operation is not allowed after it is in terminal state.

Puede cancelar una operación en segundo plano de dos maneras:

Cancelar una operación en segundo plano actualizando las operaciones en segundo plano

Actualice la fila de la backgroundoperations tabla para establecer el backgroundoperationstatecode en 2 (Bloqueado) y el backgroundoperationstatuscode en 22 (Cancelando).

La forma de actualizar la backgroundoperations tabla depende de si usa el SDK o la API web.

static void CancelBackgroundOperationRequest(
    IOrganizationService service, 
    Guid backgroundOperationId)
{
    var backgroundOperation = new Entity(
        entityName: "backgroundoperation", 
        id: backgroundOperationId)
    { 
        Attributes =
        {
            //Set state as Locked
            {"backgroundoperationstatecode", new OptionSetValue(2) },
            //Set status as Cancelling
            {"backgroundoperationstatuscode", new OptionSetValue(22) }
        }            
    }; 

    service.Update(backgroundOperation);
}

Envíe una solicitud DELETE al recurso del monitor de estado

También puede cancelar una operación en segundo plano enviando una solicitud DELETE al recurso de supervisión de estado.

Solicitud:

DELETE [Organization URI]/api/backgroundoperation/{backgroundoperationid}

Respuesta:

HTTP/1.1 200 Ok

{
    backgroundOperationStateCode: 2,
    backgroundOperationStatusCode: 22
}

Reintentos

Si se produce un error durante la ejecución de la solicitud, se reintenta hasta tres veces. Estos reintentos utilizan una estrategia de retroceso exponencial.