UiPath Documentation
marketplace
latest
false

Guía del usuario de Marketplace

Última actualización 1 de abr. de 2026

El archivo de actividad

Importante:

Este documento hace referencia a una versión obsoleta de UiPath Activity Creator para Visual Studio. Consulta la nueva documentación aquí.

Introducción

Cada actividad comienza con un archivo de clase de actividad que define sus entradas, salidas y lógica de ejecución. Para entender mejor cómo se hace esto, abre el archivo ChildActivity.cs en tu proyecto de actividad y repásalo sección por sección. Esta es una actividad simple que suma dos números y genera su suma.

Imagen de documentos

using System;
using System.Activities;
using System.Threading;
using System.Threading.Tasks;
using MyCompany.MyProduct.Activities.Properties;
using UiPath.Shared.Activities;
namespace MyCompany.MyProduct.Activities
{
    [LocalizedDisplayName(nameof(Resources.ChildActivityDisplayName))]
    [LocalizedDescription(nameof(Resources.ChildActivityDescription))]
    public class ChildActivity : AsyncTaskCodeActivity
    {
        #region Properties
        [LocalizedDisplayName(nameof(Resources.ChildActivityFirstNumberDisplayName))]
        [LocalizedDescription(nameof(Resources.ChildActivityFirstNumberDescription))]
        [LocalizedCategory(nameof(Resources.Input))]
        public InArgument<int> FirstNumber { get; set; }
        [LocalizedDisplayName(nameof(Resources.ChildActivitySecondNumberDisplayName))]
        [LocalizedDescription(nameof(Resources.ChildActivitySecondNumberDescription))]
        [LocalizedCategory(nameof(Resources.Input))]
        public InArgument<int> SecondNumber { get; set; }
        [LocalizedDisplayName(nameof(Resources.ChildActivitySumDisplayName))]
        [LocalizedDescription(nameof(Resources.ChildActivitySumDescription))]
        [LocalizedCategory(nameof(Resources.Output))]
        public OutArgument<string> Sum { get; set; }
        #endregion

        #region Constructors

        public ChildActivity()
        {
              Constraints.Add(ActivityConstraints.HasParentType<ChildActivity, ParentScope>(Resources.ValidationMessage));
        }

        #endregion

        #region Protected Methods
        protected override void CacheMetadata(CodeActivityMetadata metadata)
        {
              if (FirstNumber == null) metadata.AddValidationError(string.Format(Resources.MetadataValidationError, nameof(FirstNumber)));
              if (SecondNumber == null) metadata.AddValidationError(string.Format(Resources.MetadataValidationError, nameof(SecondNumber)));
              base.CacheMetadata(metadata);
        }
        protected override async Task<Action<AsyncCodeActivityContext>> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken)
        {
              var property = context.DataContext.GetProperties()[ParentScope.ApplicationTag];
              var app = property.GetValue(context.DataContext) as Application;

              var firstValue = FirstNumber.Get(context);
              var secondValue = SecondNumber.Get(context);

              var sum = app.Sum(firstValue, secondValue);
              return ctx =>
              {
                  Sum.Set(ctx, sum);
              };
       }
        #endregion
    }
}
using System;
using System.Activities;
using System.Threading;
using System.Threading.Tasks;
using MyCompany.MyProduct.Activities.Properties;
using UiPath.Shared.Activities;
namespace MyCompany.MyProduct.Activities
{
    [LocalizedDisplayName(nameof(Resources.ChildActivityDisplayName))]
    [LocalizedDescription(nameof(Resources.ChildActivityDescription))]
    public class ChildActivity : AsyncTaskCodeActivity
    {
        #region Properties
        [LocalizedDisplayName(nameof(Resources.ChildActivityFirstNumberDisplayName))]
        [LocalizedDescription(nameof(Resources.ChildActivityFirstNumberDescription))]
        [LocalizedCategory(nameof(Resources.Input))]
        public InArgument<int> FirstNumber { get; set; }
        [LocalizedDisplayName(nameof(Resources.ChildActivitySecondNumberDisplayName))]
        [LocalizedDescription(nameof(Resources.ChildActivitySecondNumberDescription))]
        [LocalizedCategory(nameof(Resources.Input))]
        public InArgument<int> SecondNumber { get; set; }
        [LocalizedDisplayName(nameof(Resources.ChildActivitySumDisplayName))]
        [LocalizedDescription(nameof(Resources.ChildActivitySumDescription))]
        [LocalizedCategory(nameof(Resources.Output))]
        public OutArgument<string> Sum { get; set; }
        #endregion

        #region Constructors

        public ChildActivity()
        {
              Constraints.Add(ActivityConstraints.HasParentType<ChildActivity, ParentScope>(Resources.ValidationMessage));
        }

        #endregion

        #region Protected Methods
        protected override void CacheMetadata(CodeActivityMetadata metadata)
        {
              if (FirstNumber == null) metadata.AddValidationError(string.Format(Resources.MetadataValidationError, nameof(FirstNumber)));
              if (SecondNumber == null) metadata.AddValidationError(string.Format(Resources.MetadataValidationError, nameof(SecondNumber)));
              base.CacheMetadata(metadata);
        }
        protected override async Task<Action<AsyncCodeActivityContext>> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken)
        {
              var property = context.DataContext.GetProperties()[ParentScope.ApplicationTag];
              var app = property.GetValue(context.DataContext) as Application;

              var firstValue = FirstNumber.Get(context);
              var secondValue = SecondNumber.Get(context);

              var sum = app.Sum(firstValue, secondValue);
              return ctx =>
              {
                  Sum.Set(ctx, sum);
              };
       }
        #endregion
    }
}

Importaciones y espacio de nombres

El archivo comienza con el modelo estándar. Importa algunos espacios de nombres y luego declara que esta actividad vivirá en el espacio de nombres MyCompany.MyProduct.Activities .

using System;
using System.Activities;
using System.Threading;
using System.Threading.Tasks;
using MyCompany.MyProduct.Activities.Properties;
using UiPath.Shared.Activities;
namespace MyCompany.MyProduct.Activities
{
using System;
using System.Activities;
using System.Threading;
using System.Threading.Tasks;
using MyCompany.MyProduct.Activities.Properties;
using UiPath.Shared.Activities;
namespace MyCompany.MyProduct.Activities
{

Definición de clase

Todas las clases de actividad estándar (como el ejemplo de ChildActivity) amplían AsyncTaskCodeActivity, que proporciona métodos para la validación de propiedades en tiempo de diseño y la lógica de ejecución en tiempo de ejecución, y se puede encontrar en la Carpeta compartida incluida en tu solución. Además, todas las actividades que se extienden AsyncTaskCodeActivity pueden ejecutarse de forma asíncrona, lo que permite su uso con las actividades Paralelo y Paralelo Para Cada en UiPath Studio.

[LocalizedDisplayName(nameof(Resources.ChildActivityDisplayName))]
[LocalizedDescription(nameof(Resources.ChildActivityDescription))]
public class ChildActivity : AsyncTaskCodeActivity
{
[LocalizedDisplayName(nameof(Resources.ChildActivityDisplayName))]
[LocalizedDescription(nameof(Resources.ChildActivityDescription))]
public class ChildActivity : AsyncTaskCodeActivity
{

Encima de la definición de la clase ChildActivity, verás dos atributosLocalizedDisplayName y LocalizedDescription. Estos te permiten establecer el nombre y la descripción de la información sobre herramientas de la actividad que aparece en el panel de actividades de UiPath Studio. En este ejemplo, los atributos hacen referencia a versiones localizadas de cada uno (p. ej. Resources.ChildActivityDisplayName), pero también se pueden utilizar cadenas simples. Para obtener más información sobre la localización, consulta aquí.

Imagen de documentos

Imagen de documentos

Propiedades

A continuación, se encuentran las propiedades de la actividad, que aparecen en el panel Propiedades de UiPath Studio. Cada propiedad tiene un nombre para mostrar y una descripción, al igual que la actividad de nivel superior, pero también se incluye un atributo de Categoría para ayudar a agrupar las actividades relacionadas. Observa cómo FirstNumber y SecondNumber aparecen en la categoría Entrada, pero Sum aparece en Salida.

[LocalizedDisplayName(nameof(Resources.ChildActivityFirstNumberDisplayName))]
[LocalizedDescription(nameof(Resources.ChildActivityFirstNumberDescription))]
[LocalizedCategory(nameof(Resources.Input))]
public InArgument<int> FirstNumber { get; set; }
[LocalizedDisplayName(nameof(Resources.ChildActivitySecondNumberDisplayName))]
[LocalizedDescription(nameof(Resources.ChildActivitySecondNumberDescription))]
[LocalizedCategory(nameof(Resources.Input))]
public InArgument<int> SecondNumber { get; set; }
[LocalizedDisplayName(nameof(Resources.ChildActivitySumDisplayName))]
[LocalizedDescription(nameof(Resources.ChildActivitySumDescription))]
[LocalizedCategory(nameof(Resources.Output))]
public OutArgument<int> Sum { get; set; }
[LocalizedDisplayName(nameof(Resources.ChildActivityFirstNumberDisplayName))]
[LocalizedDescription(nameof(Resources.ChildActivityFirstNumberDescription))]
[LocalizedCategory(nameof(Resources.Input))]
public InArgument<int> FirstNumber { get; set; }
[LocalizedDisplayName(nameof(Resources.ChildActivitySecondNumberDisplayName))]
[LocalizedDescription(nameof(Resources.ChildActivitySecondNumberDescription))]
[LocalizedCategory(nameof(Resources.Input))]
public InArgument<int> SecondNumber { get; set; }
[LocalizedDisplayName(nameof(Resources.ChildActivitySumDisplayName))]
[LocalizedDescription(nameof(Resources.ChildActivitySumDescription))]
[LocalizedCategory(nameof(Resources.Output))]
public OutArgument<int> Sum { get; set; }

Imagen de documentos

Las propiedades pueden declararse como tipo InArgument, InOutArgument o OutArgument y deben indicar el tipo esperado (p. Ej. string, int, ...).

Constructor

public ChildActivity()
{
     FirstNumber = 10;
     Constraints.Add(ActivityConstraints.HasParentType<ChildActivity, ParentScope>(Resources.ValidationMessage));
}
public ChildActivity()
{
     FirstNumber = 10;
     Constraints.Add(ActivityConstraints.HasParentType<ChildActivity, ParentScope>(Resources.ValidationMessage));
}

El constructor se utiliza para establecer valores predeterminados y restricciones en las propiedades.

  • En el ejemplo anterior, a la propiedad FirstNumber se le asigna un valor predeterminado de 10, que aparece en el Panel de propiedades.

    Imagen de documentos

  • Además, se coloca una restricción en la propia actividad, que requiere que esté rodeada por un ParentScope. Si no lo es, se muestra un error de validación.

    Imagen de documentos

CacheMetadata

MetadatosDeCaché proporciona la validación de las propiedades, delegados y/o actividades secundarias de una actividad. En este ejemplo, comprobamos que se han proporcionado valores para las dos propiedades de entrada, FirstNumber y SecondNumber, y arrojamos un error de validación si no se proporciona alguna. Hasta que se gestionen los errores de validación, no se ejecutará un flujo de trabajo.

protected override void CacheMetadata(CodeActivityMetadata metadata)
{
    if (FirstNumber == null) metadata.AddValidationError(string.Format(Resources.MetadataValidationError, nameof(FirstNumber)));
    if (SecondNumber == null) metadata.AddValidationError(string.Format(Resources.MetadataValidationError, nameof(SecondNumber)));
    base.CacheMetadata(metadata);
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
    if (FirstNumber == null) metadata.AddValidationError(string.Format(Resources.MetadataValidationError, nameof(FirstNumber)));
    if (SecondNumber == null) metadata.AddValidationError(string.Format(Resources.MetadataValidationError, nameof(SecondNumber)));
    base.CacheMetadata(metadata);
}

Imagen de documentos

ExecuteAsync

ExecuteAsync es donde se lleva a cabo la lógica de ejecución de la actividad.

  • Las dos primeras líneas del método consultan el contexto de la actividad (o el estado actual de la ActividadSecundaria y los elementos que la rodean) para recuperar un objeto Application del ParentScope si hay uno que lo rodea. Ten en cuenta que, debido a la restricción añadida en el constructor anterior, esta actividad nunca podrá ejecutarse si no está en ParentScope.

  • Las siguientes líneas toman los valores actuales de las propiedades FirstNumber y SecondNumber y los guardan en variables locales.

  • Las últimas líneas realizan una operación de suma en los números introducidos y establecen la propiedad Sum en este valor. Como Sum es una propiedad de salida, este valor puede ser utilizado por actividades posteriores del flujo de trabajo.

    protected override async Task<Action<AsyncCodeActivityContext>> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken)
    {
        var property = context.DataContext.GetProperties()[ParentScope.ApplicationTag];
        var app = property.GetValue(context.DataContext) as Application;
    
        var firstValue = FirstNumber.Get(context);
        var secondValue = SecondNumber.Get(context);
    
        var sum = app.Sum(firstValue, secondValue);
        return ctx =>
        {
            Sum.Set(ctx, sum);
        };
    }
    protected override async Task<Action<AsyncCodeActivityContext>> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken)
    {
        var property = context.DataContext.GetProperties()[ParentScope.ApplicationTag];
        var app = property.GetValue(context.DataContext) as Application;
    
        var firstValue = FirstNumber.Get(context);
        var secondValue = SecondNumber.Get(context);
    
        var sum = app.Sum(firstValue, secondValue);
        return ctx =>
        {
            Sum.Set(ctx, sum);
        };
    }
    
    Importante:

    Observa que el método ExecuteAsync devuelve un objeto Task<Action<AsyncCodeActivityContext>> . Se devuelve un Task para que esta actividad pueda ejecutarse de forma asíncrona. Se devuelve un Action dentro de esta tarea para permitir que se ejecuten funciones complejas después de que se haya completado cualquier operación asíncrona. En el ejemplo anterior, esta función simplemente establece el valor de Sum. Por último, Action toma un parámetro AsyncCodeActivityContext para que el contexto de esta actividad pueda ser utilizado por cualquier función que se ejecute después de que las operaciones asíncronas hayan finalizado. Si este no fuera el caso, el contexto podría perderse y Sum no sería fácilmente modificable.

¿Te ha resultado útil esta página?

Conectar

¿Necesita ayuda? Soporte

¿Quiere aprender? UiPath Academy

¿Tiene alguna pregunta? Foro de UiPath

Manténgase actualizado