Bagikan melalui


Cara: Menjalankan Alur Kerja

Topik ini adalah kelanjutan dari tutorial Memulai Windows Workflow Foundation dan membahas cara membuat host alur kerja dan menjalankan alur kerja yang ditentukan dalam topik Cara: Membuat Alur Kerja sebelumnya.

Catatan

Setiap topik dalam tutorial Memulai bergantung pada topik sebelumnya. Untuk menyelesaikan topik ini, Anda harus terlebih dahulu menyelesaikan Cara: Membuat Aktivitas dan Cara: Membuat Alur Kerja.

Untuk membuat proyek host alur kerja

  1. Buka solusi dari topik Cara: Membuat Aktivitas sebelumnya dengan menggunakan Visual Studio 2012.

  2. Klik kanan solusi WF45GettingStartedTutorial di Penjelajah Solusi dan pilih Tambahkan, Proyek Baru.

    Tip

    Jika jendela Penjelajah Solusi tidak ditampilkan, pilih Penjelajah Solusi dari menu Tampilan.

  3. Di simpul Terinstal, pilih Visual C#, Alur Kerja (atau Visual Basic, Alur Kerja).

    Catatan

    Bergantung pada bahasa pemrograman yang dikonfigurasi sebagai bahasa utama dalam Visual Studio, node Visual C# atau Visual Basic mungkin berada di node Bahasa Lainnya di node Terinstal.

    Pastikan .NET Framework 4.5 dipilih di menu drop-down versi .NET Framework. Pilih Aplikasi Konsol Alur Kerja dari daftar Alur Kerja. Ketik NumberGuessWorkflowHost ke dalam kotak Nama dan klik OK. Ini membuat aplikasi alur kerja pemula dengan dukungan hosting alur kerja dasar. Kode hosting dasar ini dimodifikasi dan digunakan untuk menjalankan aplikasi alur kerja.

  4. Klik kanan proyek NumberGuessWorkflowHost yang baru ditambahkan di Penjelajah Solusi dan pilih Tambahkan Referensi. Pilih Solusi dari daftar Tambahkan Referensi, centang kotak di samping NumberGuessWorkflowActivities, lalu klik OK.

  5. Klik kanan Workflow1.xaml di Penjelajah Solusi dan pilih Hapus. Klik OK untuk mengonfirmasi.

Untuk mengubah kode hosting alur kerja

  1. Klik dua kali Program.cs atau Module1.vb di Penjelajah Solusi untuk menampilkan kode.

    Tip

    Jika jendela Penjelajah Solusi tidak ditampilkan, pilih Penjelajah Solusi dari menu Tampilan.

    Karena proyek ini dibuat dengan menggunakan templat Aplikasi Konsol Alur Kerja, Program.cs atau Module1.vb berisi kode hosting alur kerja dasar berikut.

    ' Create and cache the workflow definition.
    Dim workflow1 As Activity = New Workflow1()
    WorkflowInvoker.Invoke(workflow1)
    
    // Create and cache the workflow definition.
    Activity workflow1 = new Workflow1();
    WorkflowInvoker.Invoke(workflow1);
    

    Kode hosting yang dihasilkan ini menggunakan WorkflowInvoker. WorkflowInvoker menyediakan cara sederhana untuk menjalankan alur kerja seolah-olah cara itu adalah pemanggilan metode dan hanya dapat digunakan untuk alur kerja yang tidak menggunakan persistensi. WorkflowApplication menyediakan model yang lebih kaya untuk menjalankan alur kerja yang mencakup pemberitahuan peristiwa siklus hidup, kontrol eksekusi, kelanjutan marka buku, dan persistensi. Contoh ini menggunakan marka buku dan WorkflowApplication digunakan untuk meng-host alur kerja. Tambahkan pernyataan using atau Impor berikut di bagian atas Program.cs atau Module1.vb di bawah pernyataan menggunakan atau Impor.

    Imports NumberGuessWorkflowActivities
    Imports System.Threading
    
    using NumberGuessWorkflowActivities;
    using System.Threading;
    

    Ganti baris kode yang menggunakan WorkflowInvoker dengan kode hosting WorkflowApplication dasar berikut. Kode hosting sampel ini menunjukkan langkah-langkah dasar untuk meng-host dan memanggil alur kerja, tetapi belum berisi fungsionalitas untuk berhasil menjalankan alur kerja dari topik ini. Pada langkah-langkah berikut, kode dasar ini dimodifikasi dan fitur tambahan ditambahkan hingga aplikasi selesai.

    Catatan

    Anda harus mengganti Workflow1 dalam contoh ini dengan FlowchartNumberGuessWorkflow, , SequentialNumberGuessWorkflowatau StateMachineNumberGuessWorkflow, tergantung pada alur kerja mana yang Anda selesaikan di langkah Cara: Membuat Alur Kerja sebelumnya. Jika Anda tidak mengganti Workflow1, Anda akan mendapatkan kesalahan build saat mencoba dan membangun atau menjalankan alur kerja.

    AutoResetEvent syncEvent = new AutoResetEvent(false);
    
    WorkflowApplication wfApp =
        new WorkflowApplication(_wf);
    
    wfApp.Completed = delegate (WorkflowApplicationCompletedEventArgs e)
    {
        syncEvent.Set();
    };
    
    wfApp.Aborted = delegate (WorkflowApplicationAbortedEventArgs e)
    {
        Console.WriteLine(e.Reason);
        syncEvent.Set();
    };
    
    wfApp.OnUnhandledException = delegate (WorkflowApplicationUnhandledExceptionEventArgs e)
    {
        Console.WriteLine(e.UnhandledException.ToString());
        return UnhandledExceptionAction.Terminate;
    };
    
    wfApp.Run();
    
    syncEvent.WaitOne();
    
    Dim syncEvent As New AutoResetEvent(False)
    
    Dim wfApp As New WorkflowApplication(New Workflow1())
    
    wfApp.Completed =
        Sub(e As WorkflowApplicationCompletedEventArgs)
            syncEvent.Set()
        End Sub
    
    wfApp.Aborted =
        Sub(e As WorkflowApplicationAbortedEventArgs)
            Console.WriteLine(e.Reason)
            syncEvent.Set()
        End Sub
    
    wfApp.OnUnhandledException =
        Function(e As WorkflowApplicationUnhandledExceptionEventArgs)
            Console.WriteLine(e.UnhandledException)
            Return UnhandledExceptionAction.Terminate
        End Function
    
    wfApp.Run()
    
    syncEvent.WaitOne()
    

    Kode ini membuat WorkflowApplication, berlangganan tiga peristiwa siklus hidup alur kerja, memulai alur kerja dengan panggilan ke Run, kemudian menunggu alur kerja selesai. Setelah alur kerja selesai, AutoResetEvent diatur dan aplikasi host selesai.

Untuk mengatur argumen input alur kerja

  1. Tambahkan pernyataan berikut di bagian atas Program.cs atau Module1.vb di bawah pernyataan using atau Imports yang sudah ada.

  2. Ganti baris kode yang membuat WorkflowApplication baru dengan kode berikut yang membuat dan meneruskan kamus parameter ke alur kerja saat dibuat.

    Catatan

    Ganti Workflow1 dalam contoh ini dengan FlowchartNumberGuessWorkflow, SequentialNumberGuessWorkflow, atau StateMachineNumberGuessWorkflow, bergantung pada alur kerja mana yang Anda selesaikan di langkah Cara: Membuat Alur Kerja sebelumnya. Jika Anda tidak mengganti Workflow1, Anda akan mendapatkan kesalahan build saat mencoba dan membangun atau menjalankan alur kerja.

    var inputs = new Dictionary<string, object>() { { "MaxNumber", 100 } };
    
    WorkflowApplication wfApp = new(_wf, inputs)
    {
    
    Dim inputs As New Dictionary(Of String, Object)
    inputs.Add("MaxNumber", 100)
    
    Dim wfApp As New WorkflowApplication(New Workflow1(), inputs)
    

    Kamus ini berisi satu elemen dengan kunci MaxNumber. Kunci dalam kamus input bersesuaian dengan argumen input pada aktivitas akar alur kerja. MaxNumber digunakan oleh alur kerja untuk menentukan batas atas untuk nomor yang dihasilkan secara acak.

Untuk mengambil argumen output alur kerja

  1. Ubah penangan Completed untuk mengambil dan menampilkan nomor giliran yang digunakan oleh alur kerja.

    Completed = delegate (WorkflowApplicationCompletedEventArgs e)
    {
        int Turns = Convert.ToInt32(e.Outputs["Turns"]);
        Console.WriteLine("Congratulations, you guessed the number in {0} turns.", Turns);
    
        syncEvent.Set();
    },
    
    wfApp.Completed =
        Sub(e As WorkflowApplicationCompletedEventArgs)
            Dim Turns As Integer = Convert.ToInt32(e.Outputs("Turns"))
            Console.WriteLine("Congratulations, you guessed the number in {0} turns.", Turns)
    
            syncEvent.Set()
        End Sub
    

Untuk melanjutkan marka buku

  1. Tambahkan kode berikut di bagian atas metode Main tepat setelah deklarasi AutoResetEvent yang sudah ada.

    AutoResetEvent idleEvent = new AutoResetEvent(false);
    
    Dim idleEvent As New AutoResetEvent(False)
    
  2. Tambahkan penangan Idle berikut tepat di bawah tiga penangan siklus hidup alur kerja yang sudah ada di Main.

        Idle = delegate (WorkflowApplicationIdleEventArgs e)
        {
            idleEvent.Set();
        }
    };
    
    wfApp.Idle =
        Sub(e As WorkflowApplicationIdleEventArgs)
            idleEvent.Set()
        End Sub
    

    Setiap kali alur kerja menjadi menganggur menunggu tebakan berikutnya, handler ini dipanggil dan idleAction AutoResetEvent diatur. Kode dalam langkah berikut menggunakan idleEvent dan syncEvent untuk menentukan apakah alur kerja menunggu tebakan berikutnya atau selesai.

    Catatan

    Dalam contoh ini, aplikasi host menggunakan peristiwa reset otomatis di penangan Completed dan Idle untuk menyinkronkan aplikasi host dengan kemajuan alur kerja. Tidak perlu memblokir dan menunggu alur kerja menganggur sebelum melanjutkan marka buku, tetapi dalam contoh ini peristiwa sinkronisasi diperlukan agar host mengetahui apakah alur kerja selesai atau apakah menunggu lebih banyak input pengguna dengan menggunakan Bookmark. Untuk informasi selengkapnya, lihat Marka Buku.

  3. Hapus panggilan ke WaitOne, dan ganti dengan kode untuk mengumpulkan input dari pengguna dan melanjutkan Bookmark.

    Hapus baris kode berikut.

    syncEvent.WaitOne();
    
    syncEvent.WaitOne()
    

    Ganti dengan contoh berikut.

    // Loop until the workflow completes.
    WaitHandle[] handles = new WaitHandle[] { syncEvent, idleEvent };
    while (WaitHandle.WaitAny(handles) != 0)
    {
        // Gather the user input and resume the bookmark.
        bool validEntry = false;
        while (!validEntry)
        {
            if (!Int32.TryParse(Console.ReadLine(), out int Guess))
            {
                Console.WriteLine("Please enter an integer.");
            }
            else
            {
                validEntry = true;
                wfApp.ResumeBookmark("EnterGuess", Guess);
            }
        }
    }
    
    ' Loop until the workflow completes.
    Dim waitHandles As WaitHandle() = New WaitHandle() {syncEvent, idleEvent}
    Do While WaitHandle.WaitAny(waitHandles) <> 0
        'Gather the user input and resume the bookmark.
        Dim validEntry As Boolean = False
        Do While validEntry = False
            Dim Guess As Integer
            If Int32.TryParse(Console.ReadLine(), Guess) = False Then
                Console.WriteLine("Please enter an integer.")
            Else
                validEntry = True
                wfApp.ResumeBookmark("EnterGuess", Guess)
            End If
        Loop
    Loop
    

Untuk membangun dan menjalankan aplikasi

  1. Klik kanan NumberGuessWorkflowHost di Penjelajah Solusi dan pilih Atur sebagai Proyek StartUp.

  2. Tekan CTRL+F5 untuk membangun dan menjalankan aplikasi. Coba tebak nomor dalam beberapa giliran sedikit mungkin.

    Untuk mencoba aplikasi dengan salah satu gaya alur kerja lainnya, ganti Workflow1 dalam kode yang membuat WorkflowApplication dengan FlowchartNumberGuessWorkflow, SequentialNumberGuessWorkflowatau StateMachineNumberGuessWorkflow, bergantung pada gaya alur kerja yang diinginkan.

    var inputs = new Dictionary<string, object>() { { "MaxNumber", 100 } };
    
    WorkflowApplication wfApp = new(_wf, inputs)
    {
    
    Dim inputs As New Dictionary(Of String, Object)
    inputs.Add("MaxNumber", 100)
    
    Dim wfApp As New WorkflowApplication(New Workflow1(), inputs)
    

    Untuk petunjuk cara menambahkan persistensi ke aplikasi alur kerja, lihat topik berikutnya, Cara: Membuat dan Menjalankan Alur Kerja Jangka Panjang.

Contoh

Contoh berikut adalah daftar kode lengkap untuk metode Main.

Catatan

Ganti Workflow1 dalam contoh ini dengan FlowchartNumberGuessWorkflow, SequentialNumberGuessWorkflow, atau StateMachineNumberGuessWorkflow, bergantung pada alur kerja mana yang Anda selesaikan di langkah Cara: Membuat Alur Kerja sebelumnya. Jika Anda tidak mengganti Workflow1, Anda akan mendapatkan kesalahan build saat mencoba dan membangun atau menjalankan alur kerja.

static void Main(string[] args)
{
    AutoResetEvent syncEvent = new AutoResetEvent(false);
    AutoResetEvent idleEvent = new AutoResetEvent(false);

    var inputs = new Dictionary<string, object>() { { "MaxNumber", 100 } };

    WorkflowApplication wfApp = new(_wf, inputs)
    {

        Completed = delegate (WorkflowApplicationCompletedEventArgs e)
        {
            int Turns = Convert.ToInt32(e.Outputs["Turns"]);
            Console.WriteLine("Congratulations, you guessed the number in {0} turns.", Turns);

            syncEvent.Set();
        },

        Aborted = delegate (WorkflowApplicationAbortedEventArgs e)
        {
            Console.WriteLine(e.Reason);
            syncEvent.Set();
        },

        OnUnhandledException = delegate (WorkflowApplicationUnhandledExceptionEventArgs e)
        {
            Console.WriteLine(e.UnhandledException.ToString());
            return UnhandledExceptionAction.Terminate;
        },

        Idle = delegate (WorkflowApplicationIdleEventArgs e)
        {
            idleEvent.Set();
        }
    };

    wfApp.Run();

    // Loop until the workflow completes.
    WaitHandle[] handles = new WaitHandle[] { syncEvent, idleEvent };
    while (WaitHandle.WaitAny(handles) != 0)
    {
        // Gather the user input and resume the bookmark.
        bool validEntry = false;
        while (!validEntry)
        {
            if (!Int32.TryParse(Console.ReadLine(), out int Guess))
            {
                Console.WriteLine("Please enter an integer.");
            }
            else
            {
                validEntry = true;
                wfApp.ResumeBookmark("EnterGuess", Guess);
            }
        }
    }
}
Sub Main()
    Dim syncEvent As New AutoResetEvent(False)
    Dim idleEvent As New AutoResetEvent(False)

    Dim inputs As New Dictionary(Of String, Object)
    inputs.Add("MaxNumber", 100)

    Dim wfApp As New WorkflowApplication(New Workflow1(), inputs)

    wfApp.Completed =
        Sub(e As WorkflowApplicationCompletedEventArgs)
            Dim Turns As Integer = Convert.ToInt32(e.Outputs("Turns"))
            Console.WriteLine("Congratulations, you guessed the number in {0} turns.", Turns)

            syncEvent.Set()
        End Sub

    wfApp.Aborted =
        Sub(e As WorkflowApplicationAbortedEventArgs)
            Console.WriteLine(e.Reason)
            syncEvent.Set()
        End Sub

    wfApp.OnUnhandledException =
        Function(e As WorkflowApplicationUnhandledExceptionEventArgs)
            Console.WriteLine(e.UnhandledException)
            Return UnhandledExceptionAction.Terminate
        End Function

    wfApp.Idle =
        Sub(e As WorkflowApplicationIdleEventArgs)
            idleEvent.Set()
        End Sub

    wfApp.Run()

    ' Loop until the workflow completes.
    Dim waitHandles As WaitHandle() = New WaitHandle() {syncEvent, idleEvent}
    Do While WaitHandle.WaitAny(waitHandles) <> 0
        'Gather the user input and resume the bookmark.
        Dim validEntry As Boolean = False
        Do While validEntry = False
            Dim Guess As Integer
            If Int32.TryParse(Console.ReadLine(), Guess) = False Then
                Console.WriteLine("Please enter an integer.")
            Else
                validEntry = True
                wfApp.ResumeBookmark("EnterGuess", Guess)
            End If
        Loop
    Loop
End Sub

Lihat juga