MarcadoresBookmarks

Los marcadores son el mecanismo que permite a una actividad esperar datos pasivamente sin tener que mantener un subproceso de flujo de trabajo.Bookmarks are the mechanism that enables an activity to passively wait for input without holding onto a workflow thread. Cuando una actividad indica que está esperando un estímulo, puede crear un marcador.When an activity signals that it is waiting for stimulus, it can create a bookmark. Esto indica al tiempo de ejecución que la ejecución de la actividad no debería considerarse completada aun cuando se devuelva el método que se está ejecutando actualmente (que creó Bookmark).This indicates to the runtime that the activity’s execution should not be considered complete even when the currently executing method (which created the Bookmark) returns.

Fundamentos de los marcadoresBookmark Basics

Bookmark representa un punto en el que la ejecución se puede reanudar (y, a través de la cual, se puede entregar los datos) dentro de una instancia de flujo de trabajo.A Bookmark represents a point at which execution can be resumed (and through which input can be delivered) within a workflow instance. Normalmente, a Bookmark se le proporciona un nombre y el código externo (host o extensión) será el responsable de reanudar el marcador con datos pertinentes.Typically, a Bookmark is given a name and external (host or extension) code is responsible for resuming the bookmark with relevant data. Cuando se reanuda Bookmark, el tiempo de ejecución del flujo de trabajo programa el delegado de BookmarkCallback que estuvo asociado con ese Bookmark en el momento de su creación.When a Bookmark is resumed, the workflow runtime schedules the BookmarkCallback delegate that was associated with that Bookmark at the time of its creation.

Opciones de marcadorBookmark Options

La clase BookmarkOptions especifica el tipo de Bookmark que se crea.The BookmarkOptions class specifies the type of Bookmark being created. Los posibles valores que no se excluyen mutuamente son None, MultipleResume y NonBlocking.The possible non mutually-exclusive values are None, MultipleResume, and NonBlocking. Use None, el valor predeterminado, al crear un Bookmark que se espera que se reanude una vez.Use None, the default, when creating a Bookmark that is expected to be resumed exactly once. Use MultipleResume al crear un Bookmark que se puede reanudar varias veces.Use MultipleResume when creating a Bookmark that can be resumed multiple times. Use NonBlocking al crear un Bookmark que posiblemente no se reanude nunca.Use NonBlocking when creating a Bookmark that might never be resumed. A diferencia de los marcadores que se crean usando el BookmarkOptionspredeterminado, los marcadores NonBlocking no impiden que se complete una actividad.Unlike bookmarks created using the default BookmarkOptions, NonBlocking bookmarks do not prevent an activity from completing.

Reanudar marcadoresBookmark Resumption

Los marcadores pueden reanudarse según el código fuera de un flujo de trabajo usando una de las sobrecargas de ResumeBookmark.Bookmarks can be resumed by code outside of a workflow using one of the ResumeBookmark overloads. En este ejemplo, se crea una actividad ReadLine.In this example, a ReadLine activity is created. Cuando se ejecuta, la actividad ReadLine crea un Bookmark, registra una devolución de llamada y, a continuación, espera a que se reanude Bookmark.When executed, the ReadLine activity creates a Bookmark, registers a callback, and then waits for the Bookmark to be resumed. Cuando lo haga, la actividad ReadLine asigna los datos que se pasaron con Bookmark a su argumento Result.When it is resumed, the ReadLine activity assigns the data that was passed with the Bookmark to its Result argument.

public sealed class ReadLine : NativeActivity<string>  
{  
    [RequiredArgument]  
    public  InArgument<string> BookmarkName { get; set; }  
  
    protected override void Execute(NativeActivityContext context)  
    {  
        // Create a Bookmark and wait for it to be resumed.  
        context.CreateBookmark(BookmarkName.Get(context),   
            new BookmarkCallback(OnResumeBookmark));  
    }  
  
    // NativeActivity derived activities that do asynchronous operations by calling   
    // one of the CreateBookmark overloads defined on System.Activities.NativeActivityContext   
    // must override the CanInduceIdle property and return true.  
    protected override bool CanInduceIdle  
    {  
        get { return true; }  
    }  
  
    public void OnResumeBookmark(NativeActivityContext context, Bookmark bookmark, object obj)  
    {  
        // When the Bookmark is resumed, assign its value to  
        // the Result argument.  
        Result.Set(context, (string)obj);  
    }  
}  

En este ejemplo, se crea un flujo de trabajo que usa la actividad ReadLine para recopilar el nombre del usuario y mostrarlo en la ventana de la consola.In this example, a workflow is created that uses the ReadLine activity to gather the user’s name and display it to the console window. La aplicación host realiza el trabajo real de recopilación de datos y los pasa al flujo de trabajo al reanudar Bookmark.The host application performs the actual work of gathering the input and passes it to the workflow by resuming the Bookmark.

Variable<string> name = new Variable<string>  
{  
    Name = "name"  
};  
  
Activity wf = new Sequence  
{  
    Variables =  
    {  
        name  
    },  
    Activities =  
    {  
        new WriteLine()  
        {  
            Text = "What is your name?"  
        },  
        new ReadLine()  
        {  
            BookmarkName = "UserName",  
            Result = name  
        },  
        new WriteLine()  
        {  
            Text = new InArgument<string>((env) => "Hello, " + name.Get(env))  
        }  
    }  
};  
  
AutoResetEvent syncEvent = new AutoResetEvent(false);  
  
// Create the WorkflowApplication using the desired  
// workflow definition.  
WorkflowApplication wfApp = new WorkflowApplication(wf);  
  
// Handle the desired lifecycle events.  
wfApp.Completed = delegate(WorkflowApplicationCompletedEventArgs e)  
{  
    // Signal the host that the workflow is complete.  
    syncEvent.Set();  
};  
  
// Start the workflow.  
wfApp.Run();  
  
// Collect the user's name and resume the bookmark.  
// Bookmark resumption only occurs when the workflow  
// is idle. If a call to ResumeBookmark is made and the workflow  
// is not idle, ResumeBookmark blocks until the workflow becomes  
// idle before resuming the bookmark.  
wfApp.ResumeBookmark("UserName", Console.ReadLine());  
  
// Wait for Completed to arrive and signal that  
// the workflow is complete.  
syncEvent.WaitOne();  

Cuando se ejecuta la actividad ReadLine, crea un Bookmark denominado UserName y, a continuación, espera a que se reanude el marcador.When the ReadLine activity is executed, it creates a Bookmark named UserName and then waits for the bookmark to be resumed. El host recopila los datos deseados y, a continuación, reanuda Bookmark.The host collects the desired data and then resumes the Bookmark. El flujo de trabajo se reanuda, muestra el nombre y, a continuación, finaliza.The workflow resumes, displays the name, and then completes. Tenga en cuenta que no se necesita el código de sincronización con respecto a la reanudación del marcador.Note that no synchronization code is required with regard to resuming the bookmark. Se puede reanudar Bookmark sólo cuando el flujo de trabajo está inactivo y, si no lo está, la llamada a ResumeBookmark se bloquea hasta que el flujo de trabajo se vuelve inactivo.A Bookmark can only be resumed when the workflow is idle, and if the workflow is not idle, the call to ResumeBookmark blocks until the workflow becomes idle.

Resultado de reanudación del marcadorBookmark Resumption Result

ResumeBookmark devuelve un valor de enumeración de BookmarkResumptionResult para indicar los resultados de la solicitud de reanudación del marcador.ResumeBookmark returns a BookmarkResumptionResult enumeration value to indicate the results of the bookmark resumption request. Los valores de devolución posibles son Success, NotReady y NotFound.The possible return values are Success, NotReady, and NotFound. Los hosts y extensiones pueden usar este valor para determinar cómo continuar.Hosts and extensions can use this value to determine how to proceed.