Dela via


Bokmärken

Bokmärken är den mekanism som gör det möjligt för en aktivitet att passivt vänta på indata utan att hålla i en arbetsflödestråd. När en aktivitet signalerar att den väntar på stimulans kan den skapa ett bokmärke. Detta indikerar för körningen att aktivitetens exekvering inte ska betraktas som fullständig även när den metod som för närvarande exekveras (som skapade Bookmark) returnerar.

Grunderna i bokmärken

En Bookmark representerar en punkt där körningen kan återupptas (och genom vilken indata kan levereras) i en arbetsflödesprocess. En Bookmark ges vanligtvis ett namn, och extern kod (värd eller tillägg) ansvarar för att återuppta bokmärket med relevant data. När en Bookmark återupptas schemalägger arbetsflödesmiljön den delegerade BookmarkCallback som var associerad med det Bookmark vid dess skapelse.

Bokmärkesalternativ

Klassen BookmarkOptions anger vilken typ av Bookmark som skapas. Möjliga icke ömsesidigt uteslutande värden är None, MultipleResumeoch NonBlocking. Använd None, standardvärdet när du skapar en Bookmark som förväntas återupptas exakt en gång. Använd MultipleResume när du skapar en Bookmark som kan återupptas flera gånger. Använd NonBlocking när du skapar en Bookmark som kanske aldrig återupptas. Till skillnad från bokmärken som skapats med standardinställningen BookmarkOptionsNonBlocking hindrar bokmärken inte en aktivitet från att slutföras.

Återtagande av bokmärke

Bokmärken kan återupptas med kod utanför ett arbetsflöde med hjälp av en av överlagringarna ResumeBookmark . I det här exemplet skapas en ReadLine aktivitet. När ReadLine-aktiviteten körs, skapas en Bookmark, ett återanrop registreras, och sedan väntar man på att Bookmark ska återupptas. När aktiviteten återupptas tilldelar den de data som skickades med ReadLine till sitt Bookmark 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);  
    }  
}  

I det här exemplet skapas ett arbetsflöde som använder ReadLine aktiviteten för att samla in användarens namn och visa det i konsolfönstret. Värdprogrammet utför det faktiska arbetet med att samla in inmatning och skickar det till arbetsflödet genom att återuppta 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();  

När ReadLine-aktiviteten körs, skapas ett objekt av typen Bookmark med namnet UserName och väntar sedan på att bokmärket ska återupptas. Värden samlar in önskade data och sedan återupptar Bookmark. Arbetsflödet återupptas, visar namnet och slutförs sedan. Observera att ingen synkroniseringskod krävs för att återuppta bokmärket. A Bookmark kan bara återupptas när arbetsflödet är inaktivt, och om arbetsflödet inte är inaktivt blockeras anropet till ResumeBookmark tills arbetsflödet blir inaktivt.

Resultat för återupptagande av bokmärke

ResumeBookmark returnerar ett BookmarkResumptionResult uppräkningsvärde för att visa resultatet av begäran om att återuppta bokmärket. Möjliga returvärden är Success, NotReadyoch NotFound. Värdar och tillägg kan använda det här värdet för att avgöra hur de ska gå vidare.