Zakładki

Zakładki to mechanizm, który umożliwia działanie pasywne oczekiwanie na dane wejściowe bez trzymania się wątku przepływu pracy. Gdy działanie sygnalizuje, że oczekuje na bodźce, może utworzyć zakładkę. Wskazuje to środowisko uruchomieniowe, że wykonanie działania nie powinno być uznawane za ukończone nawet wtedy, gdy aktualnie wykonująca metoda (która utworzyła Bookmarkobiekt ) zwraca wartość .

Podstawy zakładek

Element Bookmark reprezentuje punkt, w którym można wznowić wykonywanie (i za pomocą którego można dostarczyć dane wejściowe) w wystąpieniu przepływu pracy. Bookmark Zazwyczaj dany kod nazwy i zewnętrznego (hosta lub rozszerzenia) jest odpowiedzialny za wznowienie zakładki z odpowiednimi danymi. Gdy obiekt Bookmark zostanie wznowiony, środowisko uruchomieniowe przepływu pracy planuje BookmarkCallback delegata, który został skojarzony z nim Bookmark w momencie jego utworzenia.

Opcje zakładki

Klasa BookmarkOptions określa typ tworzonego Bookmark elementu. Możliwe wzajemnie wykluczające się wartości to None, MultipleResumei NonBlocking. Użyj Nonewartości domyślnej podczas tworzenia obiektu Bookmark , który ma zostać wznowiony dokładnie raz. Użyj MultipleResume polecenia podczas tworzenia obiektu Bookmark , który można wznowić wiele razy. Użyj NonBlocking polecenia podczas tworzenia obiektu Bookmark , który nigdy nie może zostać wznowiony. W przeciwieństwie do zakładek utworzonych przy użyciu domyślnej BookmarkOptionsNonBlocking zakładki nie uniemożliwiają ukończenia działania.

Wznowienie zakładek

Zakładki można wznowić za pomocą kodu poza przepływem pracy przy użyciu jednego z ResumeBookmark przeciążeń. W tym przykładzie zostanie ReadLine utworzone działanie. Po wykonaniu ReadLine działanie tworzy Bookmarkelement , rejestruje wywołanie zwrotne, a następnie czeka na Bookmark wznowienie działania. Po wznowieniu ReadLine działanie przypisuje dane przekazane z argumentem Bookmark .Result

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);  
    }  
}  

W tym przykładzie tworzony jest przepływ pracy, który używa ReadLine działania do zbierania nazwy użytkownika i wyświetlania go w oknie konsoli. Aplikacja hosta wykonuje rzeczywistą pracę zbierania danych wejściowych i przekazuje ją do przepływu pracy, wznawiając operację 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();  

Po wykonaniu ReadLine działania zostanie utworzone nazwane BookmarkUserName , a następnie zaczeka na wznowienie zakładki. Host zbiera żądane dane, a następnie wznawia działanie obiektu Bookmark. Przepływ pracy zostanie wznowione, wyświetli nazwę, a następnie zostanie ukończony. Należy pamiętać, że w odniesieniu do wznowienia zakładki nie jest wymagany żaden kod synchronizacji. Element Bookmark można wznowić tylko wtedy, gdy przepływ pracy jest bezczynny, a jeśli przepływ pracy nie jest bezczynny, wywołanie ResumeBookmark bloku do momentu, aż przepływ pracy stanie się bezczynny.

Wynik wznowienia zakładki

ResumeBookmarkBookmarkResumptionResult Zwraca wartość wyliczenia, aby wskazać wyniki żądania wznowienia zakładki. Możliwe wartości zwracane to Success, NotReadyi NotFound. Hosty i rozszerzenia mogą używać tej wartości, aby określić, jak kontynuować.