Eventos
Compilación de Intelligent Apps
17 mar, 21 - 21 mar, 10
Únase a la serie de reuniones para crear soluciones de inteligencia artificial escalables basadas en casos de uso reales con compañeros desarrolladores y expertos.
Regístrese ahoraEste explorador ya no se admite.
Actualice a Microsoft Edge para aprovechar las características y actualizaciones de seguridad más recientes, y disponer de soporte técnico.
WorkflowIdentity
proporciona una manera para que los desarrolladores de aplicaciones de flujo de trabajo asocien un nombre y una versión con una definición de flujo de trabajo, y para que esta información se asocie a una instancia de flujo de trabajo persistente. Los desarrolladores de aplicaciones de flujo de trabajo pueden usar esta información de identidad para habilitar escenarios como la ejecución en paralelo de varias versiones de una definición de flujo de trabajo; además esta información proporciona la piedra angular para otras funcionalidades como la actualización dinámica. Este paso del tutorial demuestra cómo usar WorkflowIdentity
para hospedar varias versiones de un flujo de trabajo simultáneamente.
En este paso del tutorial, las actividades de WriteLine
en el flujo de trabajo se modifican para proporcionar información adicional y se agrega una nueva actividad WriteLine
. Una copia del ensamblado original de flujo de trabajo queda almacenada y la aplicación de host se actualiza de tal modo que puede ejecutar tanto el flujo de trabajo original como el actualizado al mismo tiempo.
Para realizar una copia del proyecto NumberGuessWorkflowActivities
Para actualizar WorkflowVersionMap a fin de incluir las versiones de flujo de trabajo anteriores
Nota
Antes de seguir los pasos de este tema, ejecute la aplicación, inicie varios flujos de trabajo de cada tipo y realice uno o dos intentos con cada uno. Estos flujos de trabajo persistentes se utilizan en este paso y en el siguiente, Procedimiento para actualizar la definición de una instancia de flujo de trabajo en ejecución.
Abra la solución WF45GettingStartedTutorial en Visual Studio 2012 si no está abierta.
Presione CTRL+MAYÚS+B para compilar la solución.
Cierre la solución WF45GettingStartedTutorial.
Abra el Explorador de Windows y navegue hasta la carpeta donde se encuentran el archivo de solución del tutorial y las carpetas de proyecto.
Cree una carpeta denominada PreviousVersions en la misma carpeta que NumberGuessWorkflowHost y NumberGuessWorkflowActivities. Esta carpeta se usa para guardar los ensamblados que contienen las distintas versiones de los flujos de trabajo usados en los pasos de tutorial posteriores.
Navegue a la carpeta NumberGuessWorkflowActivities\bin\debug (o bin\release según la configuración del proyecto). Copie NumberGuessWorkflowActivities.dll y péguelo en la carpeta PreviousVersions.
Cambie el nombre NumberGuessWorkflowActivities.dll en la carpeta PreviousVersions a NumberGuessWorkflowActivities_v1.dll.
Nota
En los pasos de este tema se muestra una manera de administrar los ensamblados usados para contener varias versiones de los flujos de trabajo. También se pueden usar otros métodos, como el nombre seguro de los ensamblados y su registro en la memoria caché global de ensamblados.
Cree una carpeta denominada NumberGuessWorkflowActivities_du en la misma carpeta que NumberGuessWorkflowHost, NumberGuessWorkflowActivities y la carpeta PreviousVersions recién agregada y agregue todos los archivos y subcarpetas de la carpeta NumberGuessWorkflowActivities a la carpeta NumberGuessWorkflowActivities_du nueva. Esta copia de seguridad del proyecto de la versión inicial de las actividades se usa en Procedimiento para actualizar la definición de una instancia de flujo de trabajo en ejecución.
Vuelva a abrir la solución WF45GettingStartedTutorial en Visual Studio 2012.
En esta sección, se actualizan las definiciones de flujo de trabajo. Se actualizan las dos actividades de WriteLine
que proporcionan informes sobre los intentos del usuario, y se agrega una nueva actividad WriteLine
que proporciona información adicional sobre el juego una vez se ha adivinado el número.
En el Explorador de soluciones, en el proyecto NumberGuessWorkflowActivities, haga doble clic en StateMachineNumberGuessWorkflow.xaml.
Haga doble clic en la transición Intento incorrecto en la máquina de estados.
Actualice Text
de WriteLine
del extremo izquierdo en la actividad If
.
Guess & " is too low."
Guess + " is too low."
Actualice Text
de WriteLine
del extremo derecho en la actividad If
.
Guess & " is too high."
Guess + " is too high."
Vuelva a la vista global de la máquina de estados en el diseñador de flujo de trabajo; para ello, haga clic en StateMachine en la pantalla de la ruta de navegación en la parte superior del diseñador de flujo de trabajo.
Haga doble clic en la transición Intento correcto en la máquina de estados.
Arrastre una actividad WriteLine de la sección Elementos primitivos del Cuadro de herramientas y colóquela sobre la etiqueta Coloque la actividad Action aquí de la transición.
Escriba la siguiente expresión en el cuadro de propiedad Text
.
Guess & " is correct. You guessed it in " & Turns & " turns."
Guess + " is correct. You guessed it in " + Turns + " turns."
En el Explorador de soluciones, en el proyecto NumberGuessWorkflowActivities, haga doble clic en FlowchartNumberGuessWorkflow.xaml.
Actualice Text
de la actividad WriteLine
del extremo izquierdo.
Guess & " is too low."
Guess + " is too low."
Actualice Text
de la actividad WriteLine
del extremo derecho.
Guess & " is too high."
Guess + " is too high."
Arrastre una actividad WriteLine de la sección Elementos primitivos del Cuadro de herramientas y colóquela en el punto de colocación de la acción True
de FlowDecision
superior. La actividad WriteLine
se agrega al diagrama de flujo y se vincula a la acción True
de FlowDecision
.
Escriba la siguiente expresión en el cuadro de propiedad Text
.
Guess & " is correct. You guessed it in " & Turns & " turns."
Guess + " is correct. You guessed it in " + Turns + " turns."
En el Explorador de soluciones, en el proyecto NumberGuessWorkflowActivities, haga doble clic en SequentialNumberGuessWorkflow.xaml.
Actualice Text
de WriteLine
del extremo izquierdo en la actividad If
.
Guess & " is too low."
Guess + " is too low."
Actualice Text
de la actividad WriteLine
del extremo derecho en la actividad If
.
Guess & " is too high."
Guess + " is too high."
Arrastre una actividad WriteLine de la sección Elementos primitivos del Cuadro de herramientas y colóquela después de la actividad DoWhile para que WriteLine sea la actividad final en la actividad Sequence
raíz.
Escriba la siguiente expresión en el cuadro de propiedad Text
.
Guess & " is correct. You guessed it in " & Turns & " turns."
Guess + " is correct. You guessed it in " + Turns + " turns."
Haga doble clic en WorkflowVersionMap.cs (o WorkflowVersionMap.vb) del proyecto NumberGuessWorkflowHost para abrirlo.
Agregue las siguientes instrucciones using
(o Imports
) al principio del archivo con las demás instrucciones using
(o Imports
).
Imports System.Reflection
Imports System.IO
using System.Reflection;
using System.IO;
Agregue tres nuevas identidades de flujo de trabajo justo debajo de las tres declaraciones de identidad de flujo de trabajo existentes. Estas nuevas identidades de flujo de trabajo de v1
se usarán para proporcionar la definición de flujo de trabajo correcta a los flujos de trabajo iniciados antes de que se realizaran las actualizaciones.
'Current version identities.
Public StateMachineNumberGuessIdentity As WorkflowIdentity
Public FlowchartNumberGuessIdentity As WorkflowIdentity
Public SequentialNumberGuessIdentity As WorkflowIdentity
'v1 Identities.
Public StateMachineNumberGuessIdentity_v1 As WorkflowIdentity
Public FlowchartNumberGuessIdentity_v1 As WorkflowIdentity
Public SequentialNumberGuessIdentity_v1 As WorkflowIdentity
// Current version identities.
static public WorkflowIdentity StateMachineNumberGuessIdentity;
static public WorkflowIdentity FlowchartNumberGuessIdentity;
static public WorkflowIdentity SequentialNumberGuessIdentity;
// v1 identities.
static public WorkflowIdentity StateMachineNumberGuessIdentity_v1;
static public WorkflowIdentity FlowchartNumberGuessIdentity_v1;
static public WorkflowIdentity SequentialNumberGuessIdentity_v1;
En el constructor WorkflowVersionMap
, actualice la propiedad Version
de las tres identidades de flujo de trabajo actuales a 2.0.0.0
.
'Add the current workflow version identities.
StateMachineNumberGuessIdentity = New WorkflowIdentity With
{
.Name = "StateMachineNumberGuessWorkflow",
.Version = New Version(2, 0, 0, 0)
}
FlowchartNumberGuessIdentity = New WorkflowIdentity With
{
.Name = "FlowchartNumberGuessWorkflow",
.Version = New Version(2, 0, 0, 0)
}
SequentialNumberGuessIdentity = New WorkflowIdentity With
{
.Name = "SequentialNumberGuessWorkflow",
.Version = New Version(2, 0, 0, 0)
}
map.Add(StateMachineNumberGuessIdentity, New StateMachineNumberGuessWorkflow())
map.Add(FlowchartNumberGuessIdentity, New FlowchartNumberGuessWorkflow())
map.Add(SequentialNumberGuessIdentity, New SequentialNumberGuessWorkflow())
// Add the current workflow version identities.
StateMachineNumberGuessIdentity = new WorkflowIdentity
{
Name = "StateMachineNumberGuessWorkflow",
// Version = new Version(1, 0, 0, 0),
Version = new Version(2, 0, 0, 0)
};
FlowchartNumberGuessIdentity = new WorkflowIdentity
{
Name = "FlowchartNumberGuessWorkflow",
// Version = new Version(1, 0, 0, 0),
Version = new Version(2, 0, 0, 0)
};
SequentialNumberGuessIdentity = new WorkflowIdentity
{
Name = "SequentialNumberGuessWorkflow",
// Version = new Version(1, 0, 0, 0),
Version = new Version(2, 0, 0, 0)
};
map.Add(StateMachineNumberGuessIdentity, new StateMachineNumberGuessWorkflow());
map.Add(FlowchartNumberGuessIdentity, new FlowchartNumberGuessWorkflow());
map.Add(SequentialNumberGuessIdentity, new SequentialNumberGuessWorkflow());
El código que agrega las versiones actuales de los flujos de trabajo al diccionario usa las versiones actuales a las que se hace referencia en el proyecto, por lo que no es necesario actualizar el código que inicializa las definiciones de flujo de trabajo.
Agregue el código siguiente en el constructor justo después del código que agrega las versiones actuales al diccionario.
'Initialize the previous workflow version identities.
StateMachineNumberGuessIdentity_v1 = New WorkflowIdentity With
{
.Name = "StateMachineNumberGuessWorkflow",
.Version = New Version(1, 0, 0, 0)
}
FlowchartNumberGuessIdentity_v1 = New WorkflowIdentity With
{
.Name = "FlowchartNumberGuessWorkflow",
.Version = New Version(1, 0, 0, 0)
}
SequentialNumberGuessIdentity_v1 = New WorkflowIdentity With
{
.Name = "SequentialNumberGuessWorkflow",
.Version = New Version(1, 0, 0, 0)
}
// Initialize the previous workflow version identities.
StateMachineNumberGuessIdentity_v1 = new WorkflowIdentity
{
Name = "StateMachineNumberGuessWorkflow",
Version = new Version(1, 0, 0, 0)
};
FlowchartNumberGuessIdentity_v1 = new WorkflowIdentity
{
Name = "FlowchartNumberGuessWorkflow",
Version = new Version(1, 0, 0, 0)
};
SequentialNumberGuessIdentity_v1 = new WorkflowIdentity
{
Name = "SequentialNumberGuessWorkflow",
Version = new Version(1, 0, 0, 0)
};
Estas identidades de flujo de trabajo están asociadas a las versiones iniciales de las definiciones de flujo de trabajo correspondientes.
A continuación, cargue el ensamblado que contiene la versión inicial de las definiciones de flujo de trabajo, y cree y agregue las definiciones de flujo de trabajo al diccionario.
'Add the previous version workflow identities to the dictionary along with
'the corresponding workflow definitions loaded from the v1 assembly.
'Assembly.LoadFile requires an absolute path so convert this relative path
'to an absolute path.
Dim v1AssemblyPath As String = "..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v1.dll"
v1AssemblyPath = Path.GetFullPath(v1AssemblyPath)
Dim v1Assembly As Assembly = Assembly.LoadFile(v1AssemblyPath)
map.Add(StateMachineNumberGuessIdentity_v1,
v1Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow"))
map.Add(SequentialNumberGuessIdentity_v1,
v1Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow"))
map.Add(FlowchartNumberGuessIdentity_v1,
v1Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow"))
// Add the previous version workflow identities to the dictionary along with
// the corresponding workflow definitions loaded from the v1 assembly.
// Assembly.LoadFile requires an absolute path so convert this relative path
// to an absolute path.
string v1AssemblyPath = @"..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v1.dll";
v1AssemblyPath = Path.GetFullPath(v1AssemblyPath);
Assembly v1Assembly = Assembly.LoadFile(v1AssemblyPath);
map.Add(StateMachineNumberGuessIdentity_v1,
v1Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow") as Activity);
map.Add(SequentialNumberGuessIdentity_v1,
v1Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow") as Activity);
map.Add(FlowchartNumberGuessIdentity_v1,
v1Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow") as Activity);
En el ejemplo siguiente se muestra la lista completa para la clase WorkflowVersionMap
actualizada.
Public Module WorkflowVersionMap
Dim map As Dictionary(Of WorkflowIdentity, Activity)
'Current version identities.
Public StateMachineNumberGuessIdentity As WorkflowIdentity
Public FlowchartNumberGuessIdentity As WorkflowIdentity
Public SequentialNumberGuessIdentity As WorkflowIdentity
'v1 Identities.
Public StateMachineNumberGuessIdentity_v1 As WorkflowIdentity
Public FlowchartNumberGuessIdentity_v1 As WorkflowIdentity
Public SequentialNumberGuessIdentity_v1 As WorkflowIdentity
Sub New()
map = New Dictionary(Of WorkflowIdentity, Activity)
'Add the current workflow version identities.
StateMachineNumberGuessIdentity = New WorkflowIdentity With
{
.Name = "StateMachineNumberGuessWorkflow",
.Version = New Version(2, 0, 0, 0)
}
FlowchartNumberGuessIdentity = New WorkflowIdentity With
{
.Name = "FlowchartNumberGuessWorkflow",
.Version = New Version(2, 0, 0, 0)
}
SequentialNumberGuessIdentity = New WorkflowIdentity With
{
.Name = "SequentialNumberGuessWorkflow",
.Version = New Version(2, 0, 0, 0)
}
map.Add(StateMachineNumberGuessIdentity, New StateMachineNumberGuessWorkflow())
map.Add(FlowchartNumberGuessIdentity, New FlowchartNumberGuessWorkflow())
map.Add(SequentialNumberGuessIdentity, New SequentialNumberGuessWorkflow())
'Initialize the previous workflow version identities.
StateMachineNumberGuessIdentity_v1 = New WorkflowIdentity With
{
.Name = "StateMachineNumberGuessWorkflow",
.Version = New Version(1, 0, 0, 0)
}
FlowchartNumberGuessIdentity_v1 = New WorkflowIdentity With
{
.Name = "FlowchartNumberGuessWorkflow",
.Version = New Version(1, 0, 0, 0)
}
SequentialNumberGuessIdentity_v1 = New WorkflowIdentity With
{
.Name = "SequentialNumberGuessWorkflow",
.Version = New Version(1, 0, 0, 0)
}
'Add the previous version workflow identities to the dictionary along with
'the corresponding workflow definitions loaded from the v1 assembly.
'Assembly.LoadFile requires an absolute path so convert this relative path
'to an absolute path.
Dim v1AssemblyPath As String = "..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v1.dll"
v1AssemblyPath = Path.GetFullPath(v1AssemblyPath)
Dim v1Assembly As Assembly = Assembly.LoadFile(v1AssemblyPath)
map.Add(StateMachineNumberGuessIdentity_v1,
v1Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow"))
map.Add(SequentialNumberGuessIdentity_v1,
v1Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow"))
map.Add(FlowchartNumberGuessIdentity_v1,
v1Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow"))
End Sub
Public Function GetWorkflowDefinition(identity As WorkflowIdentity) As Activity
Return map(identity)
End Function
Public Function GetIdentityDescription(identity As WorkflowIdentity) As String
Return identity.ToString()
End Function
End Module
public static class WorkflowVersionMap
{
static Dictionary<WorkflowIdentity, Activity> map;
// Current version identities.
static public WorkflowIdentity StateMachineNumberGuessIdentity;
static public WorkflowIdentity FlowchartNumberGuessIdentity;
static public WorkflowIdentity SequentialNumberGuessIdentity;
// v1 identities.
static public WorkflowIdentity StateMachineNumberGuessIdentity_v1;
static public WorkflowIdentity FlowchartNumberGuessIdentity_v1;
static public WorkflowIdentity SequentialNumberGuessIdentity_v1;
static WorkflowVersionMap()
{
map = new Dictionary<WorkflowIdentity, Activity>();
// Add the current workflow version identities.
StateMachineNumberGuessIdentity = new WorkflowIdentity
{
Name = "StateMachineNumberGuessWorkflow",
// Version = new Version(1, 0, 0, 0),
Version = new Version(2, 0, 0, 0)
};
FlowchartNumberGuessIdentity = new WorkflowIdentity
{
Name = "FlowchartNumberGuessWorkflow",
// Version = new Version(1, 0, 0, 0),
Version = new Version(2, 0, 0, 0)
};
SequentialNumberGuessIdentity = new WorkflowIdentity
{
Name = "SequentialNumberGuessWorkflow",
// Version = new Version(1, 0, 0, 0),
Version = new Version(2, 0, 0, 0)
};
map.Add(StateMachineNumberGuessIdentity, new StateMachineNumberGuessWorkflow());
map.Add(FlowchartNumberGuessIdentity, new FlowchartNumberGuessWorkflow());
map.Add(SequentialNumberGuessIdentity, new SequentialNumberGuessWorkflow());
// Initialize the previous workflow version identities.
StateMachineNumberGuessIdentity_v1 = new WorkflowIdentity
{
Name = "StateMachineNumberGuessWorkflow",
Version = new Version(1, 0, 0, 0)
};
FlowchartNumberGuessIdentity_v1 = new WorkflowIdentity
{
Name = "FlowchartNumberGuessWorkflow",
Version = new Version(1, 0, 0, 0)
};
SequentialNumberGuessIdentity_v1 = new WorkflowIdentity
{
Name = "SequentialNumberGuessWorkflow",
Version = new Version(1, 0, 0, 0)
};
// Add the previous version workflow identities to the dictionary along with
// the corresponding workflow definitions loaded from the v1 assembly.
// Assembly.LoadFile requires an absolute path so convert this relative path
// to an absolute path.
string v1AssemblyPath = @"..\..\..\PreviousVersions\NumberGuessWorkflowActivities_v1.dll";
v1AssemblyPath = Path.GetFullPath(v1AssemblyPath);
Assembly v1Assembly = Assembly.LoadFile(v1AssemblyPath);
map.Add(StateMachineNumberGuessIdentity_v1,
v1Assembly.CreateInstance("NumberGuessWorkflowActivities.StateMachineNumberGuessWorkflow") as Activity);
map.Add(SequentialNumberGuessIdentity_v1,
v1Assembly.CreateInstance("NumberGuessWorkflowActivities.SequentialNumberGuessWorkflow") as Activity);
map.Add(FlowchartNumberGuessIdentity_v1,
v1Assembly.CreateInstance("NumberGuessWorkflowActivities.FlowchartNumberGuessWorkflow") as Activity);
}
public static Activity GetWorkflowDefinition(WorkflowIdentity identity)
{
return map[identity];
}
public static string GetIdentityDescription(WorkflowIdentity identity)
{
return identity.ToString();
}
}
Presione CTRL+MAYÚS+B para compilar la aplicación y, a continuación, CTRL+F5 para iniciarla.
Haga clic en Nuevo juego para iniciar un flujo de trabajo nuevo. La versión del flujo de trabajo se muestra debajo de la ventana de estado y refleja la versión actualizada del WorkflowIdentity
asociado. Anote el valor de InstanceId
para poder ver el archivo de seguimiento del flujo de trabajo cuando se complete y, a continuación, escriba números hasta que se termine el juego. Observe cómo el intento del usuario aparece en la información que se muestra en la ventana de estado en función de las actualizaciones de las actividades WriteLine
.
Please enter a number between 1 and 10
5 is too high.
Please enter a number between 1 and 10
3 is too high.
Please enter a number between 1 and 10
1 is too low.
Please enter a number between 1 and 10
Congratulations, you guessed the number in 4 turns.
Nota
Se muestra el texto actualizado de las actividades WriteLine
, pero no se muestra el resultado de la actividad final WriteLine
que se agregó en este tema. Esto se debe a que el controlador PersistableIdle
actualiza la ventana de estado. Debido a que el flujo de trabajo se completa y no queda inactivo después de la actividad final, no se llama al controlador PersistableIdle
. Sin embargo, el controlador Completed
muestra un mensaje similar en la ventana de estado. Si se desea, se puede agregar un código al controlador Completed
para extraer el texto de StringWriter
y mostrarlo en la ventana de estado.
Abra el Explorador de Windows y navegue a la carpeta NumberGuessWorkflowHost\bin\debug (o bin\release en función de la configuración del proyecto) y abra el archivo de seguimiento mediante el Bloc de notas que corresponde al flujo de trabajo completado. Si no anotó InstanceId
, puede identificar el archivo de seguimiento correcto mediante la información de Fecha de modificación en el Explorador de Windows.
Please enter a number between 1 and 10
5 is too high.
Please enter a number between 1 and 10
3 is too high.
Please enter a number between 1 and 10
1 is too low.
Please enter a number between 1 and 10
2 is correct. You guessed it in 4 turns.
La salida de WriteLine
actualizada se encuentra en el archivo de seguimiento, incluida la salida de WriteLine
que se agregó en este tema.
Vuelva a la aplicación para adivinar números y seleccione uno de los flujos de trabajo iniciado antes de que se realizaran las actualizaciones. Puede identificar la versión del flujo de trabajo seleccionado actualmente si examina la información de versión que aparece debajo de la ventana de estado. Escriba los números y observe que las actualizaciones de estado coinciden con el resultado de la actividad WriteLine
de la versión anterior y no incluyen el intento del usuario. Esto se debe a que estos flujos de trabajo usan la definición de flujo de trabajo anterior que no tiene las actualizaciones WriteLine
.
En el paso siguiente, Procedimiento para actualizar la definición de una instancia de flujo de trabajo en ejecución, las instancias del flujo de trabajo v1
en ejecución se actualizan para que puedan contener la funcionalidad nueva como las instancias v2
.
Comentarios de .NET
.NET es un proyecto de código abierto. Seleccione un vínculo para proporcionar comentarios:
Eventos
Compilación de Intelligent Apps
17 mar, 21 - 21 mar, 10
Únase a la serie de reuniones para crear soluciones de inteligencia artificial escalables basadas en casos de uso reales con compañeros desarrolladores y expertos.
Regístrese ahoraCursos
Ruta de aprendizaje
Use advance techniques in canvas apps to perform custom updates and optimization - Training
Use advance techniques in canvas apps to perform custom updates and optimization
Documentación
Usar y crear actividades - .NET Framework
Más información: Uso y creación de actividades
Obtenga más información sobre cómo actualizar la definición de una instancia de flujo de trabajo en ejecución para implementar una corrección de errores, agregar nuevos requisitos o dar cabida a cambios inesperados.
Procedimiento para crear un participante de seguimiento personalizado - .NET Framework
Más información: Procedimiento para crear un participante de seguimiento personalizado