Compartir a través de


Operaciones en segundo plano (versión preliminar)

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

Utilice operaciones en segundo plano para enviar solicitudes que Dataverse procesa de forma asíncrona. 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 API personalizadas.

Las API personalizadas usan complementos para realizar las operaciones de datos. Como todos los complementos de Dataverse, estos complementos tienen un tiempo de ejecución de dos minutos. Enviar la solicitud de forma asíncrona no proporciona más tiempo de ejecución.

Privilegios requeridos

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

Aprenda a editar un rol de seguridad.

Procesado de solicitud asincrónica

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

Los ejemplos de este artículo utilizan una API personalizada denominada sample_ExportDataUsingFetchXmlToAnnotation. Esta API personalizada se describe en Ejemplo: ExportDataUsingFetchXmlToAnnotation API personalizada.

Use el mensaje ExecuteBackgroundOperation.

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

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

Name Type Descripción
Request OrganizationRequest (Obligatorio) Contiene la solicitud que desea que se procese de forma asíncrona. El mensaje de Dataverse para la solicitud debe implementarse como una API personalizada.
CallbackUri string (Opcional) Dataverse envía una solicitud POST HTTP a esta URL cuando se completa la operación.

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

Name Type Descripción
BackgroundOperationId GUID Identifica la fila de la tabla de operaciones en segundo plano que puede usar para monitorear o cancelar el procesamiento de su solicitud.
Location string Identifica la URL del recurso del monitor de estado que puede usar para recuperar el estado de su solicitud o para cancelarla.

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

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 version='1.0'  
                                    output-format='xml-platform' 
                                    mapping='logical'>
                                <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>

Aprenda más sobre la Interfaz IOrganizationService y cómo usar mensajes con el SDK para .NET.

Administrar operaciones en segundo plano

Cuando envía una solicitud para que se procese en segundo plano, la respuesta incluye dos valores que representan diferentes métodos que puede usar para monitorear o cancelar operaciones en segundo plano.

Consultar la tabla de operaciones en segundo plano o el recurso del monitor de estado para verificar las solicitudes se conoce comúnmente como sondeo de estado. Le recomendamos que evite el sondeo excesivo porque puede afectar negativamente al rendimiento. Si es necesario, sugerimos sondear a intervalos de un minuto o más.

Tabla de operaciones en segundo plano

La tabla de operaciones en segundo plano contiene información sobre solicitudes para procesar de forma asíncrona. Esta tabla tiene el nombre lógico backgroundoperation y el nombre del conjunto de entidades backgroundoperations. Más información sobre la operación de fondo Tipo de entidad.

La siguiente tabla describe las columnas que puede usar para administrar el estado de las operaciones en segundo plano.

Display name
Nombre de esquema
Nombre lógico
Type Descripción
Operación en segundo plano
BackgroundOperationId
backgroundoperationid
Uniqueidentifier La clave principal
Estado de ejecución
StateCode
backgroundoperationstatecode
Los atributos de lista desplegable Estado de la operación en segundo plano

Opciones:
- Valor: 0, Etiqueta: Listo
- Valor: 2, Etiqueta: Bloqueado
- Valor: 3, Etiqueta: Completado
Razón para el estado
StatusCode
backgroundoperationstatuscode
Los atributos de lista desplegable Estado de la operación en segundo plano

Opciones:
- Valor: 0, Etiqueta: Esperando recursos (Estado:Listo)
- Valor: 20, Etiqueta: En curso (Estado:Bloqueado)
- Valor: 22, Etiqueta: Cancelando (Estado:Bloqueado)
- Valor: 30, Etiqueta: Exitoso (Estado: Completado)
- Valor: 31, Etiqueta: Fallido (Estado: Completado)
- Valor: 32, Etiqueta: Cancelado (Estado: Completado)
Name
Name
name
String UniqueName de la API personalizada utilizada para la operación en segundo plano
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
Memo Los parámetros de entrada que se proporcionaron 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
Memo La respuesta de la operación en segundo plano

Esta cadena es una matriz serializada JSON de Key y Value.
Hora de inicio
StartTime
starttime
Fecha y hora Cuando una operación en segundo plano empezó la ejecución
Hora de finalización
EndTime
endtime
Fecha y hora Cuando una operación en segundo plano completó la ejecución
Recuento de reintentos
RetryCount
retrycount
Número entero El número de veces que se reintentó la operación en segundo plano
Código de error
ErrorCode
errorcode
Número entero El código de error si la operación en segundo plano falla

Si el error proviene 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 vino de Dataverse, el valor se establece en cero.
Mensaje de error.
ErrorMessage
errormessage
Memo El mensaje de error si la operación en segundo plano falla
Ejecutar como
RunAs
runas
String El systemuserid del systemuser utilizado para ejecutar la operación en segundo plano
Creadas el
CreatedOn
createdon
Fecha y hora Cuando se creó el registro
Período de vida
TTLInSeconds
ttlinseconds
Número entero Tiempo de vida en segundos, después de lo 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 su consulta:

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

La forma en que sondee la tabla depende de si está utilizando 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 en espera:

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:  

Error en la salida:

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 listados en el Códigos de error del servicio web. Si la plataforma no produce el error, el valor se establece en cero.

Id no encontrado:

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 la operación se completa, proporciona el resultado de la API personalizada. Si hubo 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},
}

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

Las etiquetas no están disponibles con el recurso del monitor de estado.

Recibir notificaciones 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 devolución de llamada

Puede especificar una URL en su solicitud para recibir una devolución de llamada cuando se complete la operación. Dataverse utiliza esta URL para enviar una solicitud POST con la siguiente carga útil:

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

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

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

Si la URL requiere autenticación, debe ser una URL de firma de acceso compartido (SAS) autosuficiente. No es posible incluir más encabezados para incluir claves 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. Los siguientes ejemplos envían una solicitud mediante un webhook a webhook.site para realizar pruebas.

Con el SDK, configure el parámetro ExecuteBackgroundOperation.CallbackUri a la 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 version='1.0'  
                                    output-format='xml-platform' 
                                    mapping='logical'>
                                <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 forma de recibir una notificación cuando finaliza una operación en segundo plano es registrar un paso en el mensaje OnBackgroundOperationComplete. Este mensaje es una API personalizada que solo permite registros de pasos asíncronos. Es un ejemplo del tipo de mensajes creados con una API personalizada para representar eventos comerciales.

Como sugiere el nombre, el evento OnBackgroundOperationComplete se produce cada vez que se completa una operación en segundo plano. Cuando registra 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 un webhook. Más información:

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

Parámetros de entrada:

Name Type Descripción
PayloadType Número entero 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 la ubicación
BackgroundOperationId GUID ID de la operación de segundo plano

Parámetros de salida:

Name Type Descripción
OperationName String Nombre de operación
BackgroundOperationStateCode Número entero Código de estado de la operación en segundo plano
BackgroundOperationStatusCode Número entero Código de estado de la operación en segundo plano

Configure el mensaje OnBackgroundOperationComplete como se muestra en las instrucciones para registrar un complemento. Asegúrese de configurar el nombre del mensaje como OnBackgroundOperationComplete. Establezca Eliminación automática en true para que el registro Trabajo del sistema (Operación asincrónica) se registre automáticamente remoto.

Cancelar operaciones en segundo plano

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

  • Si la operación no ha comenzado, Dataverse no la ejecuta.
  • Si la operación ha comenzado, Dataverse no la detiene.
  • Si se produce un error durante la ejecución de una operación en segundo plano que canceló, Dataverse no vuelve a intentarlo.
  • 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 cualquiera de las dos maneras siguientes:

Cancele una operación en segundo plano actualizando backgroundoperations

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

La forma en que actualice la tabla backgroundoperations depende de si está utilizando 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);
}

Enviar una solicitud DELETE al recurso de supervisión de estado

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

Solicitud:

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

Respuesta:

HTTP/1.1 200 Ok

{
    backgroundOperationStateCode: 2,
    backgroundOperationStatusCode: 22
}

Retries

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