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
Buka solusi dari topik Cara: Membuat Aktivitas sebelumnya dengan menggunakan Visual Studio 2012.
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.
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.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.
Klik kanan Workflow1.xaml di Penjelajah Solusi dan pilih Hapus. Klik OK untuk mengonfirmasi.
Untuk mengubah kode hosting alur kerja
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 denganFlowchartNumberGuessWorkflow
, ,SequentialNumberGuessWorkflow
atauStateMachineNumberGuessWorkflow
, tergantung pada alur kerja mana yang Anda selesaikan di langkah Cara: Membuat Alur Kerja sebelumnya. Jika Anda tidak menggantiWorkflow1
, 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
Tambahkan pernyataan berikut di bagian atas Program.cs atau Module1.vb di bawah pernyataan
using
atauImports
yang sudah ada.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 denganFlowchartNumberGuessWorkflow
,SequentialNumberGuessWorkflow
, atauStateMachineNumberGuessWorkflow
, bergantung pada alur kerja mana yang Anda selesaikan di langkah Cara: Membuat Alur Kerja sebelumnya. Jika Anda tidak menggantiWorkflow1
, 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
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
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)
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 menggunakanidleEvent
dansyncEvent
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.
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
Klik kanan NumberGuessWorkflowHost di Penjelajah Solusi dan pilih Atur sebagai Proyek StartUp.
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 denganFlowchartNumberGuessWorkflow
,SequentialNumberGuessWorkflow
atauStateMachineNumberGuessWorkflow
, 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