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, defina la operación como una API personalizada. Para más información, consulte Creación y uso de API personalizadas y recuperación de 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. Para obtener más información sobre esta API personalizada, vea 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 procesar 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. Evite un sondeo excesivo porque puede afectar negativamente al rendimiento. Si es necesario, sondee 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 que se usa 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 genera el error, establezca su valor 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 de supervisión de estado mediante una solicitud GET. Esta solicitud 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 produce 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 devuelve la solicitud original en el encabezado de respuesta Location.

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},
}

La respuesta incluye los valores backgroundOperationErrorCode y backgroundOperationErrorMessage solo cuando se produce un error. Incluye parámetros de salida solo cuando la operación se completa correctamente.

El recurso del monitor de estado no proporciona etiquetas.

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 dirección URL en la solicitud para recibir una devolución de llamada cuando finalice 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 la devolución de llamada debe enviar una solicitud GET autenticada mediante la URL del recurso de monitorización de estado para recuperar los resultados.

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

Para probar la dirección URL de devolución de llamada, considere la posibilidad de usar un sitio como webhook.site.

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 para webhook.site para realizar pruebas.

Mediante 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

Puede obtener una notificación cuando finalice una operación en segundo plano registrando un paso en el OnBackgroundOperationComplete mensaje. Este mensaje es una API personalizada que solo admite 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. Para obtener más información, consulte:

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 Tipo de respuesta enviada al URI de devolución de llamada cuando finaliza la operación en segundo plano. Siempre cero para las 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. Establezca 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 comenzó.

  • Si la operación no se inició, Dataverse no la ejecuta.
  • Si se inició la operación, Dataverse no la 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, el sistema reintenta hasta tres veces. Estos reintentos utilizan una estrategia de retroceso exponencial.