Uzun süre çalışan bir iş akışı oluşturma ve çalıştırma

Windows Workflow Foundation'ın (WF) temel özelliklerinden biri, çalışma zamanının boş iş akışlarını bir veritabanına kalıcı hale getirebilmesi ve kaldırabilmesidir. Nasıl yapılır: İş Akışı Çalıştırma'daki adımlar, konsol uygulaması kullanarak iş akışı barındırmanın temellerini göstermiştir. İş akışlarını başlatma, iş akışı yaşam döngüsü işleyicileri ve yer işaretlerini devam ettiren örnekler gösterilmiştir. İş akışı kalıcılığını etkili bir şekilde göstermek için, birden çok iş akışı örneğini başlatmayı ve devam ettiren daha karmaşık bir iş akışı konağı gereklidir. Öğreticideki bu adım, birden çok iş akışı örneğini başlatmayı ve devam ettirmeyi, iş akışı kalıcılığını destekleyen bir Windows form konak uygulamasının nasıl oluşturulacağını gösterir ve sonraki öğretici adımlarında gösterilen izleme ve sürüm oluşturma gibi gelişmiş özellikler için bir temel sağlar.

Not

Bu öğretici adımı ve sonraki adımlar, Nasıl yapılır: İş Akışı Oluşturma bölümünden üç iş akışı türünü de kullanır.

Kalıcılık veritabanını oluşturmak için

  1. SQL Server Management Studio'yu açın ve yerel sunucuya bağlanın, örneğin .\SQLEXPRESS. Yerel sunucuda Veritabanları düğümüne sağ tıklayın ve Yeni Veritabanı'nı seçin. Yeni veritabanına WF45GettingStartedTutorial adını verin, diğer tüm değerleri kabul edin ve Tamam'ı seçin.

    Not

    Veritabanını oluşturmadan önce yerel sunucuda Veritabanı Oluşturma iznine sahip olduğunuzdan emin olun.

  2. Dosya menüsünden Aç, Dosya'yı seçin. Şu klasöre göz atın: C:\Windows\Microsoft.NET\Framework\v4.0.30319\sql\en

    Aşağıdaki iki dosyayı seçin ve Aç'a tıklayın.

    • SqlWorkflowInstanceStoreLogic.sql

    • SqlWorkflowInstanceStoreSchema.sql

  3. Pencere menüsünden SqlWorkflowInstanceStoreSchema.sql seçin. Kullanılabilir Veritabanları açılan listesinde WF45GettingStartedTutorial seçeneğinin belirlendiğinden emin olun ve Sorgu menüsünden Yürüt'e tıklayın.

  4. Pencere menüsünden SqlWorkflowInstanceStoreLogic.sql seçin. Kullanılabilir Veritabanları açılan listesinde WF45GettingStartedTutorial seçeneğinin belirlendiğinden emin olun ve Sorgu menüsünden Yürüt'e tıklayın.

    Uyarı

    Önceki iki adımı doğru sırada gerçekleştirmek önemlidir. Sorgular düzgün yürütülmezse hatalar oluşur ve kalıcılık veritabanı doğru yapılandırılmaz.

DurableInstancing derlemelerine başvuru eklemek için

  1. Çözüm Gezgini'da NumberGuessWorkflowHost'a sağ tıklayın ve Başvuru Ekle'yi seçin.

  2. Başvuru Ekle listesinden Derlemeler'i seçin ve Derlemeleri Ara kutusuna yazınDurableInstancing. Bu, derlemeleri filtreler ve istenen başvuruların seçilmesini kolaylaştırır.

  3. Arama Sonuçları listesinde System.Activities.DurableInstancing ve System.Runtime.DurableInstancing'in yanındaki onay kutusunu işaretleyin ve Tamam'a tıklayın.

İş akışı ana bilgisayar formunu oluşturmak için

  1. Çözüm Gezgini'da NumberGuessWorkflowHost'a sağ tıklayın ve Ekle, Yeni Öğe'yi seçin.

  2. Yüklü şablonlar listesinde Windows Formu'nu seçin, Ad kutusuna yazın WorkflowHostForm ve Ekle'ye tıklayın.

  3. Formda aşağıdaki özellikleri yapılandırın.

    Özellik Değer
    FormBorderStyle FixedSingle
    MaximizeBox False
    Size 400, 420
  4. Forma belirtilen sırayla aşağıdaki denetimleri ekleyin ve özellikleri yönlendirildi olarak yapılandırın.

    Control Özellik: Değer
    Düğme Ad: NewGame

    Konum: 13, 13

    Boyut: 75, 23

    Metin: Yeni Oyun
    Etiket Konum: 94, 18

    Metin: 1 ile bir sayıyı tahmin etme
    ComboBox Ad: NumberRange

    DropDownStyle: DropDownList

    Öğeler: 10, 100, 1000

    Konum: 228, 12

    Boyut: 143, 21
    Etiket Konum: 13, 43

    Metin: İş akışı türü
    ComboBox Ad: WorkflowType

    DropDownStyle: DropDownList

    Öğeler: StateMachineNumberGuessWorkflow, FlowchartNumberGuessWorkflow, SequentialNumberGuessWorkflow

    Konum: 94, 40

    Boyut: 277, 21
    Etiket Ad: WorkflowVersion

    Konum: 13, 362

    Metin: İş akışı sürümü
    GroupBox Konum: 13, 67

    Boyut: 358, 287

    Metin: Oyun

    Not

    Aşağıdaki denetimleri eklerken, bunları GroupBox'a yerleştirin.

    Control Özellik: Değer
    Etiket Konum: 7, 20

    Metin: İş Akışı Örneği Kimliği
    ComboBox Ad: InstanceId

    DropDownStyle: DropDownList

    Konum: 121, 17

    Boyut: 227, 21
    Etiket Konum: 7, 47

    Metin: Tahmin
    TextBox Ad: Tahmin

    Konum: 50, 44

    Boyut: 65, 20
    Düğme Ad: EnterGuess

    Konum: 121, 42

    Boyut: 75, 23

    Metin: Tahmin Girin
    Düğme Ad: QuitGame

    Konum: 274, 42

    Boyut: 75, 23

    Metin: Çık
    TextBox Ad: WorkflowStatus

    Konum: 10, 73

    Çok Satırlı: True

    ReadOnly: True

    ScrollBars: Dikey

    Boyut: 338, 208
  5. Formun AcceptButton özelliğini EnterGuess olarak ayarlayın.

Aşağıdaki örnekte tamamlanmış form gösterilmektedir.

Windows Workflow Foundation İş Akışı Ana Bilgisayar Formunun ekran görüntüsü.

Formun özelliklerini ve yardımcı yöntemlerini eklemek için

Bu bölümdeki adımlar, form sınıfına, çalıştırma ve numaralandırma sayısı tahmin iş akışlarını desteklemek için formun kullanıcı arabirimini yapılandıran özellikler ve yardımcı yöntemler ekler.

  1. Çözüm Gezgini'da WorkflowHostForm'a sağ tıklayın ve Kodu Görüntüle'yi seçin.

  2. Dosyanın en üstüne aşağıdaki using (veya Imports) deyimlerini diğer using (veya Imports) deyimleriyle ekleyin.

    Imports System.Activities
    Imports System.Activities.DurableInstancing
    Imports System.Data.SqlClient
    Imports System.IO
    Imports System.Windows.Forms
    
    using System.Activities;
    using System.Activities.DurableInstancing;
    using System.Data.SqlClient;
    using System.IO;
    using System.Windows.Forms;
    
  3. WorkflowHostForm sınıfına aşağıdaki üye bildirimlerini ekleyin.

    Önemli

    Microsoft, kullanılabilir en güvenli kimlik doğrulama akışını kullanmanızı önerir. Azure SQL'e bağlanıyorsanız önerilen kimlik doğrulama yöntemi Azure kaynakları için Yönetilen Kimlikler'dir.

    Const connectionString = "Server=.\SQLEXPRESS;Initial Catalog=WF45GettingStartedTutorial;Integrated Security=SSPI"
    Dim store As SqlWorkflowInstanceStore
    Dim workflowStarting As Boolean
    
    const string connectionString = "Server=.\\SQLEXPRESS;Initial Catalog=WF45GettingStartedTutorial;Integrated Security=SSPI";
    SqlWorkflowInstanceStore store;
    bool workflowStarting;
    

    Not

    bağlantı dizesi farklıysa, veritabanınıza başvurmak için güncelleştirinconnectionString.

  4. sınıfına WorkflowFormHost bir WorkflowInstanceId özellik ekleyin.

    Public ReadOnly Property WorkflowInstanceId() As Guid
        Get
            If InstanceId.SelectedIndex = -1 Then
                Return Guid.Empty
            Else
                Return New Guid(InstanceId.SelectedItem.ToString())
            End If
        End Get
    End Property
    
    public Guid WorkflowInstanceId
    {
        get
        {
            return InstanceId.SelectedIndex == -1 ? Guid.Empty : (Guid)InstanceId.SelectedItem;
        }
    }
    

    Birleşik InstanceId giriş kutusu kalıcı iş akışı örneği kimliklerinin listesini görüntüler ve WorkflowInstanceId özelliği seçili durumdaki iş akışını döndürür.

  5. Form Load olayı için bir işleyici ekleyin. İşleyiciyi eklemek için formun Tasarım Görünümü'ne geçin, Özellikler penceresinin üst kısmındaki Olaylar simgesine tıklayın ve Yükle'ye çift tıklayın.

    Private Sub WorkflowHostForm_Load(sender As Object, e As EventArgs) Handles Me.Load
    
    End Sub
    
    private void WorkflowHostForm_Load(object sender, EventArgs e)
    {
    
    }
    
  6. Aşağıdaki kodu WorkflowHostForm_Load içine ekleyin.

    ' Initialize the store and configure it so that it can be used for
    ' multiple WorkflowApplication instances.
    store = New SqlWorkflowInstanceStore(connectionString)
    WorkflowApplication.CreateDefaultInstanceOwner(store, Nothing, WorkflowIdentityFilter.Any)
    
    ' Set default ComboBox selections.
    NumberRange.SelectedIndex = 0
    WorkflowType.SelectedIndex = 0
    
    ListPersistedWorkflows()
    
    // Initialize the store and configure it so that it can be used for
    // multiple WorkflowApplication instances.
    store = new SqlWorkflowInstanceStore(connectionString);
    WorkflowApplication.CreateDefaultInstanceOwner(store, null, WorkflowIdentityFilter.Any);
    
    // Set default ComboBox selections.
    NumberRange.SelectedIndex = 0;
    WorkflowType.SelectedIndex = 0;
    
    ListPersistedWorkflows();
    

    Form yüklendiğinde, SqlWorkflowInstanceStore yapılandırılır, aralık ve iş akışı türü birleşik giriş kutuları varsayılan değerlere ayarlanır ve kalıcı iş akışı örnekleri birleşik giriş kutusuna InstanceId eklenir.

  7. için InstanceIdbir SelectedIndexChanged işleyici ekleyin. İşleyiciyi eklemek için formun Tasarım Görünümü'ne geçin, birleşik giriş kutusunu seçinInstanceId, Özellikler penceresinin üst kısmındaki Olaylar simgesine tıklayın ve SelectedIndexChanged öğesine çift tıklayın.

    Private Sub InstanceId_SelectedIndexChanged(sender As Object, e As EventArgs) Handles InstanceId.SelectedIndexChanged
    
    End Sub
    
    private void InstanceId_SelectedIndexChanged(object sender, EventArgs e)
    {
    
    }
    
  8. Aşağıdaki kodu InstanceId_SelectedIndexChanged içine ekleyin. Kullanıcı birleşik giriş kutusunu kullanarak bir iş akışı seçtiğinde bu işleyici durum penceresini güncelleştirir.

    If InstanceId.SelectedIndex = -1 Then
        Return
    End If
    
    ' Clear the status window.
    WorkflowStatus.Clear()
    
    ' Get the workflow version and display it.
    ' If the workflow is just starting then this info will not
    ' be available in the persistence store so do not try and retrieve it.
    If Not workflowStarting Then
        Dim instance As WorkflowApplicationInstance = _
            WorkflowApplication.GetInstance(WorkflowInstanceId, store)
    
        WorkflowVersion.Text = _
            WorkflowVersionMap.GetIdentityDescription(instance.DefinitionIdentity)
    
        ' Unload the instance.
        instance.Abandon()
    End If
    
    if (InstanceId.SelectedIndex == -1)
    {
        return;
    }
    
    // Clear the status window.
    WorkflowStatus.Clear();
    
    // Get the workflow version and display it.
    // If the workflow is just starting then this info will not
    // be available in the persistence store so do not try and retrieve it.
    if (!workflowStarting)
    {
        WorkflowApplicationInstance instance =
            WorkflowApplication.GetInstance(this.WorkflowInstanceId, store);
    
        WorkflowVersion.Text =
            WorkflowVersionMap.GetIdentityDescription(instance.DefinitionIdentity);
    
        // Unload the instance.
        instance.Abandon();
    }
    
  9. Form sınıfına aşağıdaki ListPersistedWorkflows yöntemi ekleyin.

    Private Sub ListPersistedWorkflows()
        Using localCon As New SqlConnection(connectionString)
            Dim localCmd As String = _
                "SELECT [InstanceId] FROM [System.Activities.DurableInstancing].[Instances] ORDER BY [CreationTime]"
    
            Dim cmd As SqlCommand = localCon.CreateCommand()
            cmd.CommandText = localCmd
            localCon.Open()
            Using reader As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
    
                While (reader.Read())
                    ' Get the InstanceId of the persisted Workflow.
                    Dim id As Guid = Guid.Parse(reader(0).ToString())
                    InstanceId.Items.Add(id)
                End While
            End Using
        End Using
    End Sub
    
    using (var localCon = new SqlConnection(connectionString))
    {
        string localCmd =
            "SELECT [InstanceId] FROM [System.Activities.DurableInstancing].[Instances] ORDER BY [CreationTime]";
    
        SqlCommand cmd = localCon.CreateCommand();
        cmd.CommandText = localCmd;
        localCon.Open();
        using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
        {
            while (reader.Read())
            {
                // Get the InstanceId of the persisted Workflow.
                Guid id = Guid.Parse(reader[0].ToString());
                InstanceId.Items.Add(id);
            }
        }
    }
    

    ListPersistedWorkflows kalıcı iş akışı örnekleri için örnek depoyu sorgular ve örnek kimliklerini birleşik giriş kutusuna cboInstanceId ekler.

  10. Form sınıfına aşağıdaki UpdateStatus yöntemi ve ilgili temsilciyi ekleyin. Bu yöntem, formdaki durum penceresini çalışmakta olan iş akışının durumuyla güncelleştirir.

    Private Delegate Sub UpdateStatusDelegate(msg As String)
    Public Sub UpdateStatus(msg As String)
        ' We may be on a different thread so we need to
        ' make this call using BeginInvoke.
        If InvokeRequired Then
            BeginInvoke(New UpdateStatusDelegate(AddressOf UpdateStatus), msg)
        Else
            If Not msg.EndsWith(vbCrLf) Then
                msg = msg & vbCrLf
            End If
    
            WorkflowStatus.AppendText(msg)
    
            ' Ensure that the newly added status is visible.
            WorkflowStatus.SelectionStart = WorkflowStatus.Text.Length
            WorkflowStatus.ScrollToCaret()
        End If
    End Sub
    
    private delegate void UpdateStatusDelegate(string msg);
    public void UpdateStatus(string msg)
    {
        // We may be on a different thread so we need to
        // make this call using BeginInvoke.
        if (InvokeRequired)
        {
            BeginInvoke(new UpdateStatusDelegate(UpdateStatus), msg);
        }
        else
        {
            if (!msg.EndsWith("\r\n"))
            {
                msg += "\r\n";
            }
            WorkflowStatus.AppendText(msg);
    
            WorkflowStatus.SelectionStart = WorkflowStatus.Text.Length;
            WorkflowStatus.ScrollToCaret();
        }
    }
    
  11. Form sınıfına aşağıdaki GameOver yöntemi ve ilgili temsilciyi ekleyin. Bir iş akışı tamamlandığında, bu yöntem InstanceId birleşik giriş kutusundan tamamlanan iş akışının örnek kimliğini kaldırarak form kullanıcı arabirimini güncelleştirir.

    Private Delegate Sub GameOverDelegate()
    Private Sub GameOver()
        If InvokeRequired Then
            BeginInvoke(New GameOverDelegate(AddressOf GameOver))
        Else
            ' Remove this instance from the InstanceId combo box.
            InstanceId.Items.Remove(InstanceId.SelectedItem)
            InstanceId.SelectedIndex = -1
        End If
    End Sub
    
    private delegate void GameOverDelegate();
    private void GameOver()
    {
        if (InvokeRequired)
        {
            BeginInvoke(new GameOverDelegate(GameOver));
        }
        else
        {
            // Remove this instance from the combo box.
            InstanceId.Items.Remove(InstanceId.SelectedItem);
            InstanceId.SelectedIndex = -1;
        }
    }
    

Örnek depoyu, iş akışı yaşam döngüsü işleyicilerini ve uzantıları yapılandırmak için

  1. Form sınıfına bir ConfigureWorkflowApplication yöntem ekleyin.

    Private Sub ConfigureWorkflowApplication(wfApp As WorkflowApplication)
    
    End Sub
    
    private void ConfigureWorkflowApplication(WorkflowApplication wfApp)
    {
    }
    

    Bu yöntem, öğesini WorkflowApplicationyapılandırarak istenen uzantıları ekler ve iş akışı yaşam döngüsü olayları için işleyiciler ekler.

  2. içinde ConfigureWorkflowApplicationiçin öğesini SqlWorkflowInstanceStore WorkflowApplicationbelirtin.

    ' Configure the persistence store.
    wfApp.InstanceStore = store
    
    // Configure the persistence store.
    wfApp.InstanceStore = store;
    
  3. Ardından bir StringWriter örnek oluşturun ve koleksiyonuna Extensions WorkflowApplicationekleyin. Uzantılara bir StringWriter eklendiğinde tüm WriteLine etkinlik çıkışını yakalar. İş akışı boşta olduğunda, WriteLine çıkış öğesinden StringWriter ayıklanabilir ve formda görüntülenebilir.

    ' Add a StringWriter to the extensions. This captures the output
    ' from the WriteLine activities so we can display it in the form.
    Dim sw As New StringWriter()
    wfApp.Extensions.Add(sw)
    
    // Add a StringWriter to the extensions. This captures the output
    // from the WriteLine activities so we can display it in the form.
    var sw = new StringWriter();
    wfApp.Extensions.Add(sw);
    
  4. Olay için aşağıdaki işleyiciyi Completed ekleyin. bir iş akışı başarıyla tamamlandığında, sayının tahminine yönelik dönüş sayısı durum penceresinde görüntülenir. İş akışı sonlandırılırsa sonlandırmaya neden olan özel durum bilgileri görüntülenir. İşleyicinin GameOver sonunda, tamamlanan iş akışını iş akışı listesinden kaldıran yöntemi çağrılır.

    wfApp.Completed = _
        Sub(e As WorkflowApplicationCompletedEventArgs)
            If e.CompletionState = ActivityInstanceState.Faulted Then
                UpdateStatus($"Workflow Terminated. Exception: {e.TerminationException.GetType().FullName}{vbCrLf}{e.TerminationException.Message}")
            ElseIf e.CompletionState = ActivityInstanceState.Canceled Then
                UpdateStatus("Workflow Canceled.")
            Else
                Dim turns As Integer = Convert.ToInt32(e.Outputs("Turns"))
                UpdateStatus($"Congratulations, you guessed the number in {turns} turns.")
            End If
            GameOver()
        End Sub
    
    wfApp.Completed = delegate(WorkflowApplicationCompletedEventArgs e)
    {
        if (e.CompletionState == ActivityInstanceState.Faulted)
        {
            UpdateStatus($"Workflow Terminated. Exception: {e.TerminationException.GetType().FullName}\r\n{e.TerminationException.Message}");
        }
        else if (e.CompletionState == ActivityInstanceState.Canceled)
        {
            UpdateStatus("Workflow Canceled.");
        }
        else
        {
            int turns = Convert.ToInt32(e.Outputs["Turns"]);
            UpdateStatus($"Congratulations, you guessed the number in {turns} turns.");
        }
        GameOver();
    };
    
  5. Aşağıdaki Aborted ve OnUnhandledException işleyicilerini ekleyin. İş GameOver akışı örneği durdurulduğunda sonlandırılmadığından ve örneği daha sonra sürdürmek mümkün olduğundan yöntemi işleyiciden Aborted çağrılmaz.

    wfApp.Aborted = _
        Sub(e As WorkflowApplicationAbortedEventArgs)
            UpdateStatus($"Workflow Aborted. Exception: {e.Reason.GetType().FullName}{vbCrLf}{e.Reason.Message}")
        End Sub
    
    wfApp.OnUnhandledException = _
        Function(e As WorkflowApplicationUnhandledExceptionEventArgs)
            UpdateStatus($"Unhandled Exception: {e.UnhandledException.GetType().FullName}{vbCrLf}{e.UnhandledException.Message}")
            GameOver()
            Return UnhandledExceptionAction.Terminate
        End Function
    
    wfApp.Aborted = delegate(WorkflowApplicationAbortedEventArgs e)
    {
        UpdateStatus($"Workflow Aborted. Exception: {e.Reason.GetType().FullName}\r\n{e.Reason.Message}");
    };
    
    wfApp.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
    {
        UpdateStatus($"Unhandled Exception: {e.UnhandledException.GetType().FullName}\r\n{e.UnhandledException.Message}");
        GameOver();
        return UnhandledExceptionAction.Terminate;
    };
    
  6. Aşağıdaki PersistableIdle işleyiciyi ekleyin. Bu işleyici eklenen uzantıyı StringWriter alır, etkinliklerden WriteLine çıkışı ayıklar ve durum penceresinde görüntüler.

    wfApp.PersistableIdle = _
        Function(e As WorkflowApplicationIdleEventArgs)
            ' Send the current WriteLine outputs to the status window.
            Dim writers = e.GetInstanceExtensions(Of StringWriter)()
            For Each writer In writers
                UpdateStatus(writer.ToString())
            Next
            Return PersistableIdleAction.Unload
        End Function
    
    wfApp.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e)
    {
        // Send the current WriteLine outputs to the status window.
        var writers = e.GetInstanceExtensions<StringWriter>();
        foreach (var writer in writers)
        {
            UpdateStatus(writer.ToString());
        }
        return PersistableIdleAction.Unload;
    };
    

    Sabit PersistableIdleAction listesi üç değere sahiptir: None, Persist, ve Unload. Persist iş akışının kalıcı olmasını sağlar, ancak iş akışının kaldırılmasına neden olmaz. Unload iş akışının kalıcı hale gelip kaldırılmasına neden olur.

    Aşağıdaki örnek, tamamlanmış ConfigureWorkflowApplication yöntemdir.

    Private Sub ConfigureWorkflowApplication(wfApp As WorkflowApplication)
        ' Configure the persistence store.
        wfApp.InstanceStore = store
    
        ' Add a StringWriter to the extensions. This captures the output
        ' from the WriteLine activities so we can display it in the form.
        Dim sw As New StringWriter()
        wfApp.Extensions.Add(sw)
    
        wfApp.Completed = _
            Sub(e As WorkflowApplicationCompletedEventArgs)
                If e.CompletionState = ActivityInstanceState.Faulted Then
                    UpdateStatus($"Workflow Terminated. Exception: {e.TerminationException.GetType().FullName}{vbCrLf}{e.TerminationException.Message}")
                ElseIf e.CompletionState = ActivityInstanceState.Canceled Then
                    UpdateStatus("Workflow Canceled.")
                Else
                    Dim turns As Integer = Convert.ToInt32(e.Outputs("Turns"))
                    UpdateStatus($"Congratulations, you guessed the number in {turns} turns.")
                End If
                GameOver()
            End Sub
    
        wfApp.Aborted = _
            Sub(e As WorkflowApplicationAbortedEventArgs)
                UpdateStatus($"Workflow Aborted. Exception: {e.Reason.GetType().FullName}{vbCrLf}{e.Reason.Message}")
            End Sub
    
        wfApp.OnUnhandledException = _
            Function(e As WorkflowApplicationUnhandledExceptionEventArgs)
                UpdateStatus($"Unhandled Exception: {e.UnhandledException.GetType().FullName}{vbCrLf}{e.UnhandledException.Message}")
                GameOver()
                Return UnhandledExceptionAction.Terminate
            End Function
    
        wfApp.PersistableIdle = _
            Function(e As WorkflowApplicationIdleEventArgs)
                ' Send the current WriteLine outputs to the status window.
                Dim writers = e.GetInstanceExtensions(Of StringWriter)()
                For Each writer In writers
                    UpdateStatus(writer.ToString())
                Next
                Return PersistableIdleAction.Unload
            End Function
    End Sub
    
    private void ConfigureWorkflowApplication(WorkflowApplication wfApp)
    {
        // Configure the persistence store.
        wfApp.InstanceStore = store;
    
        // Add a StringWriter to the extensions. This captures the output
        // from the WriteLine activities so we can display it in the form.
        var sw = new StringWriter();
        wfApp.Extensions.Add(sw);
    
        wfApp.Completed = delegate(WorkflowApplicationCompletedEventArgs e)
        {
            if (e.CompletionState == ActivityInstanceState.Faulted)
            {
                UpdateStatus($"Workflow Terminated. Exception: {e.TerminationException.GetType().FullName}\r\n{e.TerminationException.Message}");
            }
            else if (e.CompletionState == ActivityInstanceState.Canceled)
            {
                UpdateStatus("Workflow Canceled.");
            }
            else
            {
                int turns = Convert.ToInt32(e.Outputs["Turns"]);
                UpdateStatus($"Congratulations, you guessed the number in {turns} turns.");
            }
            GameOver();
        };
    
        wfApp.Aborted = delegate(WorkflowApplicationAbortedEventArgs e)
        {
            UpdateStatus($"Workflow Aborted. Exception: {e.Reason.GetType().FullName}\r\n{e.Reason.Message}");
        };
    
        wfApp.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
        {
            UpdateStatus($"Unhandled Exception: {e.UnhandledException.GetType().FullName}\r\n{e.UnhandledException.Message}");
            GameOver();
            return UnhandledExceptionAction.Terminate;
        };
    
        wfApp.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e)
        {
            // Send the current WriteLine outputs to the status window.
            var writers = e.GetInstanceExtensions<StringWriter>();
            foreach (var writer in writers)
            {
                UpdateStatus(writer.ToString());
            }
            return PersistableIdleAction.Unload;
        };
    }
    

Birden çok iş akışı türünün başlatılmasını ve devam ettirilmesine olanak tanımak için

Bir iş akışı örneğini sürdürmek için konağın iş akışı tanımını sağlaması gerekir. Bu öğreticide üç iş akışı türü vardır ve sonraki öğretici adımları bu türlerin birden çok sürümünü tanıtır. WorkflowIdentity bir konak uygulamasının tanımlayıcı bilgileri kalıcı bir iş akışı örneğiyle ilişkilendirmesi için bir yol sağlar. Bu bölümdeki adımlarda, kalıcı bir iş akışı örneğinden ilgili iş akışı tanımına iş akışı kimliğini eşlemeye yardımcı olacak bir yardımcı program sınıfının nasıl oluşturulacağı gösterilmektedir. Ve sürüm oluşturma hakkında WorkflowIdentity daha fazla bilgi için bkz . WorkflowIdentity ve Versioning kullanma.

  1. Çözüm Gezgini'da NumberGuessWorkflowHost'a sağ tıklayın ve Ekle, Sınıf'ı seçin. Ad kutusuna yazın WorkflowVersionMap ve Ekle'ye tıklayın.

  2. Dosyanın en üstüne aşağıdaki using veya Imports deyimlerini diğer using veya Imports deyimleriyle ekleyin.

    Imports System.Activities
    Imports NumberGuessWorkflowActivities
    
    using System.Activities;
    using NumberGuessWorkflowActivities;
    
  3. sınıf bildirimini WorkflowVersionMap aşağıdaki bildirimle değiştirin.

    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
    
        Sub New()
            map = New Dictionary(Of WorkflowIdentity, Activity)
    
            ' Add the current workflow version identities.
            StateMachineNumberGuessIdentity = New WorkflowIdentity With
            {
                .Name = "StateMachineNumberGuessWorkflow",
                .Version = New Version(1, 0, 0, 0)
            }
    
            FlowchartNumberGuessIdentity = New WorkflowIdentity With
            {
                .Name = "FlowchartNumberGuessWorkflow",
                .Version = New Version(1, 0, 0, 0)
            }
    
            SequentialNumberGuessIdentity = New WorkflowIdentity With
            {
                .Name = "SequentialNumberGuessWorkflow",
                .Version = New Version(1, 0, 0, 0)
            }
    
            map.Add(StateMachineNumberGuessIdentity, New StateMachineNumberGuessWorkflow())
            map.Add(FlowchartNumberGuessIdentity, New FlowchartNumberGuessWorkflow())
            map.Add(SequentialNumberGuessIdentity, New SequentialNumberGuessWorkflow())
        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;
    
        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)
            };
    
            FlowchartNumberGuessIdentity = new WorkflowIdentity
            {
                Name = "FlowchartNumberGuessWorkflow",
                Version = new Version(1, 0, 0, 0)
            };
    
            SequentialNumberGuessIdentity = new WorkflowIdentity
            {
                Name = "SequentialNumberGuessWorkflow",
                Version = new Version(1, 0, 0, 0)
            };
    
            map.Add(StateMachineNumberGuessIdentity, new StateMachineNumberGuessWorkflow());
            map.Add(FlowchartNumberGuessIdentity, new FlowchartNumberGuessWorkflow());
            map.Add(SequentialNumberGuessIdentity, new SequentialNumberGuessWorkflow());
        }
    
        public static Activity GetWorkflowDefinition(WorkflowIdentity identity)
        {
            return map[identity];
        }
    
        public static string GetIdentityDescription(WorkflowIdentity identity)
        {
            return identity.ToString();
       }
    }
    

    WorkflowVersionMap bu öğreticideki üç iş akışı tanımıyla eşlenen üç iş akışı kimliği içerir ve iş akışları başlatıldığında ve sürdürülürken aşağıdaki bölümlerde kullanılır.

Yeni bir iş akışı başlatmak için

  1. için NewGamebir Click işleyici ekleyin. İşleyiciyi eklemek için formun Tasarım Görünümü'ne geçin ve öğesine çift tıklayınNewGame. İşleyici NewGame_Click eklenir ve görünüm formun kod görünümüne geçer. Kullanıcı bu düğmeye her tıkladığınızda yeni bir iş akışı başlatılır.

    Private Sub NewGame_Click(sender As Object, e As EventArgs) Handles NewGame.Click
    
    End Sub
    
    private void NewGame_Click(object sender, EventArgs e)
    {
    
    }
    
  2. Tıklama işleyicisine aşağıdaki kodu ekleyin. Bu kod, iş akışı için bağımsız değişken adıyla anahtarlanan giriş bağımsız değişkenlerinden oluşan bir sözlük oluşturur. Bu sözlük, aralık birleşik giriş kutusundan alınan rastgele oluşturulan sayının aralığını içeren bir girdiye sahiptir.

    Dim inputs As New Dictionary(Of String, Object)()
    inputs.Add("MaxNumber", Convert.ToInt32(NumberRange.SelectedItem))
    
    var inputs = new Dictionary<string, object>();
    inputs.Add("MaxNumber", Convert.ToInt32(NumberRange.SelectedItem));
    
  3. Ardından, iş akışını başlatan aşağıdaki kodu ekleyin. WorkflowIdentity Seçilen iş akışı türüne karşılık gelen ve iş akışı tanımı yardımcı sınıfı kullanılarak WorkflowVersionMap alınır. Ardından, giriş bağımsız değişkenlerinin iş akışı tanımı, WorkflowIdentityve sözlüğü kullanılarak yeni WorkflowApplication bir örnek oluşturulur.

    Dim identity As WorkflowIdentity = Nothing
    Select Case WorkflowType.SelectedItem.ToString()
        Case "SequentialNumberGuessWorkflow"
            identity = WorkflowVersionMap.SequentialNumberGuessIdentity
    
        Case "StateMachineNumberGuessWorkflow"
            identity = WorkflowVersionMap.StateMachineNumberGuessIdentity
    
        Case "FlowchartNumberGuessWorkflow"
            identity = WorkflowVersionMap.FlowchartNumberGuessIdentity
    End Select
    
    Dim wf As Activity = WorkflowVersionMap.GetWorkflowDefinition(identity)
    
    Dim wfApp = New WorkflowApplication(wf, inputs, identity)
    
    WorkflowIdentity identity = null;
    switch (WorkflowType.SelectedItem.ToString())
    {
        case "SequentialNumberGuessWorkflow":
            identity = WorkflowVersionMap.SequentialNumberGuessIdentity;
            break;
    
        case "StateMachineNumberGuessWorkflow":
            identity = WorkflowVersionMap.StateMachineNumberGuessIdentity;
            break;
    
        case "FlowchartNumberGuessWorkflow":
            identity = WorkflowVersionMap.FlowchartNumberGuessIdentity;
            break;
    };
    
    Activity wf = WorkflowVersionMap.GetWorkflowDefinition(identity);
    
    WorkflowApplication wfApp = new WorkflowApplication(wf, inputs, identity);
    
  4. Ardından, iş akışını iş akışı listesine ekleyen ve formda iş akışının sürüm bilgilerini görüntüleyen aşağıdaki kodu ekleyin.

    ' Add the workflow to the list and display the version information.
    workflowStarting = True
    InstanceId.SelectedIndex = InstanceId.Items.Add(wfApp.Id)
    WorkflowVersion.Text = identity.ToString()
    workflowStarting = False
    
    // Add the workflow to the list and display the version information.
    workflowStarting = true;
    InstanceId.SelectedIndex = InstanceId.Items.Add(wfApp.Id);
    WorkflowVersion.Text = identity.ToString();
    workflowStarting = false;
    
  5. Bu WorkflowApplication örnek için örnek depoyu, uzantıları ve iş akışı yaşam döngüsü işleyicilerini yapılandırmak için çağrısı ConfigureWorkflowApplication yapın.

    ' Configure the instance store, extensions, and
    ' workflow lifecycle handlers.
    ConfigureWorkflowApplication(wfApp)
    
    // Configure the instance store, extensions, and
    // workflow lifecycle handlers.
    ConfigureWorkflowApplication(wfApp);
    
  6. Son olarak öğesini arayın Run.

    ' Start the workflow.
    wfApp.Run()
    
    // Start the workflow.
    wfApp.Run();
    

    Aşağıdaki örnek tamamlanmış NewGame_Click işleyicidir.

    Private Sub NewGame_Click(sender As Object, e As EventArgs) Handles NewGame.Click
        ' Start a new workflow.
        Dim inputs As New Dictionary(Of String, Object)()
        inputs.Add("MaxNumber", Convert.ToInt32(NumberRange.SelectedItem))
    
        Dim identity As WorkflowIdentity = Nothing
        Select Case WorkflowType.SelectedItem.ToString()
            Case "SequentialNumberGuessWorkflow"
                identity = WorkflowVersionMap.SequentialNumberGuessIdentity
    
            Case "StateMachineNumberGuessWorkflow"
                identity = WorkflowVersionMap.StateMachineNumberGuessIdentity
    
            Case "FlowchartNumberGuessWorkflow"
                identity = WorkflowVersionMap.FlowchartNumberGuessIdentity
        End Select
    
        Dim wf As Activity = WorkflowVersionMap.GetWorkflowDefinition(identity)
    
        Dim wfApp = New WorkflowApplication(wf, inputs, identity)
    
        ' Add the workflow to the list and display the version information.
        workflowStarting = True
        InstanceId.SelectedIndex = InstanceId.Items.Add(wfApp.Id)
        WorkflowVersion.Text = identity.ToString()
        workflowStarting = False
    
        ' Configure the instance store, extensions, and
        ' workflow lifecycle handlers.
        ConfigureWorkflowApplication(wfApp)
    
        ' Start the workflow.
        wfApp.Run()
    End Sub
    
    private void NewGame_Click(object sender, EventArgs e)
    {
        var inputs = new Dictionary<string, object>();
        inputs.Add("MaxNumber", Convert.ToInt32(NumberRange.SelectedItem));
    
        WorkflowIdentity identity = null;
        switch (WorkflowType.SelectedItem.ToString())
        {
            case "SequentialNumberGuessWorkflow":
                identity = WorkflowVersionMap.SequentialNumberGuessIdentity;
                break;
    
            case "StateMachineNumberGuessWorkflow":
                identity = WorkflowVersionMap.StateMachineNumberGuessIdentity;
                break;
    
            case "FlowchartNumberGuessWorkflow":
                identity = WorkflowVersionMap.FlowchartNumberGuessIdentity;
                break;
        };
    
        Activity wf = WorkflowVersionMap.GetWorkflowDefinition(identity);
    
        var wfApp = new WorkflowApplication(wf, inputs, identity);
    
        // Add the workflow to the list and display the version information.
        workflowStarting = true;
        InstanceId.SelectedIndex = InstanceId.Items.Add(wfApp.Id);
        WorkflowVersion.Text = identity.ToString();
        workflowStarting = false;
    
        // Configure the instance store, extensions, and
        // workflow lifecycle handlers.
        ConfigureWorkflowApplication(wfApp);
    
        // Start the workflow.
        wfApp.Run();
    }
    

bir iş akışını sürdürmek için

  1. için EnterGuessbir Click işleyici ekleyin. İşleyiciyi eklemek için formun Tasarım Görünümü'ne geçin ve öğesine çift tıklayınEnterGuess. Kullanıcı bu düğmeye her tıkladığınızda bir iş akışı sürdürülür.

    Private Sub EnterGuess_Click(sender As Object, e As EventArgs) Handles EnterGuess.Click
    
    End Sub
    
    private void EnterGuess_Click(object sender, EventArgs e)
    {
    
    }
    
  2. İş akışı listesinde bir iş akışının seçildiğinden ve kullanıcının tahmininin geçerli olduğundan emin olmak için aşağıdaki kodu ekleyin.

    If WorkflowInstanceId = Guid.Empty Then
        MessageBox.Show("Please select a workflow.")
        Return
    End If
    
    Dim userGuess As Integer
    If Not Int32.TryParse(Guess.Text, userGuess) Then
        MessageBox.Show("Please enter an integer.")
        Guess.SelectAll()
        Guess.Focus()
        Return
    End If
    
    if (WorkflowInstanceId == Guid.Empty)
    {
        MessageBox.Show("Please select a workflow.");
        return;
    }
    
    int guess;
    if (!Int32.TryParse(Guess.Text, out guess))
    {
        MessageBox.Show("Please enter an integer.");
        Guess.SelectAll();
        Guess.Focus();
        return;
    }
    
  3. Ardından kalıcı iş akışı örneğinin değerini alın WorkflowApplicationInstance . A WorkflowApplicationInstance , henüz bir iş akışı tanımıyla ilişkilendirilmemiş kalıcı bir iş akışı örneğini temsil eder. DefinitionIdentity, WorkflowApplicationInstance kalıcı iş akışı örneğinin öğesini içerirWorkflowIdentity. Bu öğreticide WorkflowVersionMap yardımcı program sınıfı, öğesini doğru iş akışı tanımıyla eşlemek WorkflowIdentity için kullanılır. İş akışı tanımı alındıktan sonra, doğru iş akışı tanımı kullanılarak bir WorkflowApplication oluşturulur.

    Dim instance As WorkflowApplicationInstance = _
        WorkflowApplication.GetInstance(WorkflowInstanceId, store)
    
    ' Use the persisted WorkflowIdentity to retrieve the correct workflow
    ' definition from the dictionary.
    Dim wf As Activity = _
        WorkflowVersionMap.GetWorkflowDefinition(instance.DefinitionIdentity)
    
    ' Associate the WorkflowApplication with the correct definition
    Dim wfApp As New WorkflowApplication(wf, instance.DefinitionIdentity)
    
    WorkflowApplicationInstance instance =
        WorkflowApplication.GetInstance(WorkflowInstanceId, store);
    
    // Use the persisted WorkflowIdentity to retrieve the correct workflow
    // definition from the dictionary.
    Activity wf =
        WorkflowVersionMap.GetWorkflowDefinition(instance.DefinitionIdentity);
    
    // Associate the WorkflowApplication with the correct definition
    var wfApp = new WorkflowApplication(wf, instance.DefinitionIdentity);
    
  4. WorkflowApplication oluşturulduktan sonra çağrısı yaparak ConfigureWorkflowApplicationörnek depoyu, iş akışı yaşam döngüsü işleyicilerini ve uzantıları yapılandırın. Bu adımlar her yeni WorkflowApplication oluşturulduğunda ve iş akışı örneği içine WorkflowApplicationyüklenmeden önce yapılmalıdır. İş akışı yüklendikten sonra kullanıcının tahminiyle sürdürülür.

    ' Configure the extensions and lifecycle handlers.
    ' Do this before the instance is loaded. Once the instance is
    ' loaded it is too late to add extensions.
    ConfigureWorkflowApplication(wfApp)
    
    ' Load the workflow.
    wfApp.Load(instance)
    
    ' Resume the workflow.
    wfApp.ResumeBookmark("EnterGuess", userGuess)
    
    // Configure the extensions and lifecycle handlers.
    // Do this before the instance is loaded. Once the instance is
    // loaded it is too late to add extensions.
    ConfigureWorkflowApplication(wfApp);
    
    // Load the workflow.
    wfApp.Load(instance);
    
    // Resume the workflow.
    wfApp.ResumeBookmark("EnterGuess", guess);
    
  5. Son olarak, tahmin metin kutusunu temizleyin ve formu başka bir tahmini kabul etmek için hazırlayın.

    ' Clear the Guess textbox.
    Guess.Clear()
    Guess.Focus()
    
    // Clear the Guess textbox.
    Guess.Clear();
    Guess.Focus();
    

    Aşağıdaki örnek tamamlanmış EnterGuess_Click işleyicidir.

    Private Sub EnterGuess_Click(sender As Object, e As EventArgs) Handles EnterGuess.Click
        If WorkflowInstanceId = Guid.Empty Then
            MessageBox.Show("Please select a workflow.")
            Return
        End If
    
        Dim userGuess As Integer
        If Not Int32.TryParse(Guess.Text, userGuess) Then
            MessageBox.Show("Please enter an integer.")
            Guess.SelectAll()
            Guess.Focus()
            Return
        End If
    
        Dim instance As WorkflowApplicationInstance = _
            WorkflowApplication.GetInstance(WorkflowInstanceId, store)
    
        ' Use the persisted WorkflowIdentity to retrieve the correct workflow
        ' definition from the dictionary.
        Dim wf As Activity = _
            WorkflowVersionMap.GetWorkflowDefinition(instance.DefinitionIdentity)
    
        ' Associate the WorkflowApplication with the correct definition
        Dim wfApp As New WorkflowApplication(wf, instance.DefinitionIdentity)
    
        ' Configure the extensions and lifecycle handlers.
        ' Do this before the instance is loaded. Once the instance is
        ' loaded it is too late to add extensions.
        ConfigureWorkflowApplication(wfApp)
    
        ' Load the workflow.
        wfApp.Load(instance)
    
        ' Resume the workflow.
        wfApp.ResumeBookmark("EnterGuess", userGuess)
    
        ' Clear the Guess textbox.
        Guess.Clear()
        Guess.Focus()
    End Sub
    
    private void EnterGuess_Click(object sender, EventArgs e)
    {
        if (WorkflowInstanceId == Guid.Empty)
        {
            MessageBox.Show("Please select a workflow.");
            return;
        }
    
        int guess;
        if (!Int32.TryParse(Guess.Text, out guess))
        {
            MessageBox.Show("Please enter an integer.");
            Guess.SelectAll();
            Guess.Focus();
            return;
        }
    
        WorkflowApplicationInstance instance =
            WorkflowApplication.GetInstance(WorkflowInstanceId, store);
    
        // Use the persisted WorkflowIdentity to retrieve the correct workflow
        // definition from the dictionary.
        Activity wf =
            WorkflowVersionMap.GetWorkflowDefinition(instance.DefinitionIdentity);
    
        // Associate the WorkflowApplication with the correct definition
        var wfApp = new WorkflowApplication(wf, instance.DefinitionIdentity);
    
        // Configure the extensions and lifecycle handlers.
        // Do this before the instance is loaded. Once the instance is
        // loaded it is too late to add extensions.
        ConfigureWorkflowApplication(wfApp);
    
        // Load the workflow.
        wfApp.Load(instance);
    
        // Resume the workflow.
        wfApp.ResumeBookmark("EnterGuess", guess);
    
        // Clear the Guess textbox.
        Guess.Clear();
        Guess.Focus();
    }
    

İş akışını sonlandırmak için

  1. için QuitGamebir Click işleyici ekleyin. İşleyiciyi eklemek için formun Tasarım Görünümü'ne geçin ve öğesine çift tıklayınQuitGame. Kullanıcı bu düğmeye her tıkladığınızda seçili olan iş akışı sonlandırılır.

    Private Sub QuitGame_Click(sender As Object, e As EventArgs) Handles QuitGame.Click
    
    End Sub
    
    private void QuitGame_Click(object sender, EventArgs e)
    {
    
    }
    
  2. İşleyiciye QuitGame_Click aşağıdaki kodu ekleyin. Bu kod önce iş akışı listesinde bir iş akışının seçildiğinden emin olmak için denetler. Ardından kalıcı örneği içine WorkflowApplicationInstanceyükler, doğru iş akışı tanımını belirlemek için öğesini DefinitionIdentity kullanır ve ardından öğesini WorkflowApplicationbaşlatır. Ardından uzantılar ve iş akışı yaşam döngüsü işleyicileri çağrısıyla ConfigureWorkflowApplicationyapılandırılır. WorkflowApplication yapılandırıldıktan sonra yüklenir ve çağrılırTerminate.

    If WorkflowInstanceId = Guid.Empty Then
        MessageBox.Show("Please select a workflow.")
        Return
    End If
    
    Dim instance As WorkflowApplicationInstance = _
        WorkflowApplication.GetInstance(WorkflowInstanceId, store)
    
    ' Use the persisted WorkflowIdentity to retrieve the correct workflow
    ' definition from the dictionary.
    Dim wf As Activity = WorkflowVersionMap.GetWorkflowDefinition(instance.DefinitionIdentity)
    
    ' Associate the WorkflowApplication with the correct definition.
    Dim wfApp As New WorkflowApplication(wf, instance.DefinitionIdentity)
    
    ' Configure the extensions and lifecycle handlers.
    ConfigureWorkflowApplication(wfApp)
    
    ' Load the workflow.
    wfApp.Load(instance)
    
    ' Terminate the workflow.
    wfApp.Terminate("User resigns.")
    
    if (WorkflowInstanceId == Guid.Empty)
    {
        MessageBox.Show("Please select a workflow.");
        return;
    }
    
    WorkflowApplicationInstance instance =
        WorkflowApplication.GetInstance(WorkflowInstanceId, store);
    
    // Use the persisted WorkflowIdentity to retrieve the correct workflow
    // definition from the dictionary.
    Activity wf = WorkflowVersionMap.GetWorkflowDefinition(instance.DefinitionIdentity);
    
    // Associate the WorkflowApplication with the correct definition
    var wfApp = new WorkflowApplication(wf, instance.DefinitionIdentity);
    
    // Configure the extensions and lifecycle handlers
    ConfigureWorkflowApplication(wfApp);
    
    // Load the workflow.
    wfApp.Load(instance);
    
    // Terminate the workflow.
    wfApp.Terminate("User resigns.");
    

Uygulamayı derlemek ve çalıştırmak için

  1. Kodu görüntülemek için Çözüm Gezgini'da Program.cs (veya Module1.vb) çift tıklayın.

  2. Dosyanın en üstüne aşağıdaki using (veya Imports) deyimini diğer using (veya Imports) deyimleriyle ekleyin.

    Imports System.Windows.Forms
    
    using System.Windows.Forms;
    
  3. Nasıl yapılır: İş Akışı Çalıştırma'dan mevcut iş akışı barındırma kodunu kaldırın veya açıklama satırı yapın ve aşağıdaki kodla değiştirin.

    Sub Main()
        Application.EnableVisualStyles()
        Application.Run(New WorkflowHostForm())
    End Sub
    
    static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.Run(new WorkflowHostForm());
    }
    
  4. Çözüm Gezgini'da NumberGuessWorkflowHost'a sağ tıklayın ve Özellikler'i seçin. Uygulama sekmesinde, Çıkış türü için Windows Uygulaması'nı belirtin. Bu adım isteğe bağlıdır, ancak izlenmiyorsa forma ek olarak konsol penceresi de görüntülenir.

  5. Uygulamayı derlemek için Ctrl+Shift+B tuşlarına basın.

  6. NumberGuessWorkflowHost'un başlangıç uygulaması olarak ayarlandığından emin olun ve uygulamayı başlatmak için Ctrl+F5 tuşlarına basın.

  7. Tahmin oyunu ve başlatacak iş akışı türü için bir aralık seçin ve Yeni Oyun'a tıklayın. Tahmin kutusuna bir tahmin girin ve tahmininizi göndermek için Git'e tıklayın. Etkinliklerden elde edilen çıkışın WriteLine formda görüntülendiğini unutmayın.

  8. Farklı iş akışı türleri ve sayı aralıkları kullanarak birkaç iş akışı başlatın, bazı tahminler girin ve İş Akışı Örneği Kimliği listesinden seçim yaparak iş akışları arasında geçiş yapın.

    Yeni bir iş akışına geçtiğinizde, iş akışının önceki tahminlerinin ve ilerleme durumunun durum penceresinde görüntülenmediğini unutmayın. Durumun kullanılabilir olmamasının nedeni, herhangi bir yerde yakalanmaması ve kaydedilmemesidir. Öğreticinin bir sonraki adımı olan Nasıl yapılır: Özel İzleme Katılımcısı Oluşturma bölümünde, bu bilgileri kaydeden özel bir izleme katılımcısı oluşturacaksınız.