Обучение
Схема обучения
Добавление логики в консольные приложения C# (начало работы с C#, часть 3) - Training
Развивайте свои навыки работы с логикой C# и операторами итерации, логическими выражениями и блоками кода в этой схеме обучения.
Этот браузер больше не поддерживается.
Выполните обновление до Microsoft Edge, чтобы воспользоваться новейшими функциями, обновлениями для системы безопасности и технической поддержкой.
Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Этот раздел продолжает учебник "Приступая к работе" для Windows Workflow Foundation и показывает, как создать узел рабочего процесса и выполнить рабочий процесс, описанный в предыдущем разделе How to: Create a Workflow .
Примечание
Каждый раздел в учебнике «Приступая к работе» построен на основе предыдущих разделов. Для изучения этого раздела необходимо сначала пройти руководства How to: Create an Activity и How to: Create a Workflow.
Откройте решение из предыдущей инструкции . Создание раздела действий с помощью Visual Studio 2012.
Щелкните правой кнопкой мыши решение WF45GettingStartedTutorial в окне Обозреватель решений и выберите Добавить, Создать проект.
Совет
Если окно Обозреватель решений не отображается, в меню Вид выберите пункт Обозреватель решений .
В узле Установленные выберите пункты Visual C#и Рабочий процесс (или Visual Basicи Рабочий процесс).
Примечание
В зависимости от того, какой язык программирования задан как основной в Visual Studio, узел Visual C# или Visual Basic может находиться в разделе Другие языки узла Установленные .
Убедитесь, что в раскрывающемся списке версий .NET Framework выбран пункт .NET Framework 4.5 . В списке Рабочий процесс выберите Консольное приложение рабочего процесса . Введите NumberGuessWorkflowHost
в поле Имя и нажмите кнопку ОК. Будет создано начальное приложение рабочего процесса с базовой поддержкой размещения рабочего процесса. Этот базовый код размещения изменяется и используется для выполнения приложения рабочего процесса.
Щелкните правой кнопкой мыши созданный проект NumberGuessWorkflowHost в обозревателе решений и выберите Добавить ссылку. Выберите Решение из списка Добавление ссылки , установите флажок рядом с NumberGuessWorkflowActivitiesи нажмите кнопку ОК.
Щелкните правой кнопкой мыши Workflow1.xaml в окне Обозреватель решений и выберите Удалить. Нажмите кнопку ОК для подтверждения.
В Solution Explorer дважды щелкните Program.cs или Module1.vb для вывода кода.
Совет
Если окно Обозреватель решений не отображается, в меню Вид выберите пункт Обозреватель решений .
Поскольку этот проект был создан с помощью шаблона Консольное приложение рабочего процесса , Program.cs или Module1.vb содержит следующий базовый код размещения рабочего процесса.
' 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);
Этот код размещения использует WorkflowInvoker. WorkflowInvoker предоставляет простой способ вызова рабочего процесса аналогично вызову метода и может использоваться только для рабочих процессов, не использующих сохраняемость. WorkflowApplication предоставляет улучшенную модель выполнения рабочих процессов, которая включает уведомления о событиях жизненного цикла, управление выполнением, возобновление закладок и сохраняемость. В этом примере используются закладки, а для размещения рабочего процесса используется WorkflowApplication . Добавьте инструкцию using
или Imports в начало файла Program.cs или Module1.vb после существующих инструкций using или Imports .
Imports NumberGuessWorkflowActivities
Imports System.Threading
using NumberGuessWorkflowActivities;
using System.Threading;
Замените строки кода, использующие WorkflowInvoker , следующим базовым кодом размещения WorkflowApplication . Этот образец кода размещения показывает основные шаги по размещению и вызову рабочего процесса, но пока не обладает достаточной функциональностью для успешного выполнения рабочего процесса, описанного в данном разделе. В ходе следующих шагов этот базовый код модифицируется и добавляются дополнительные функции, пока приложение не будет полностью готово.
Примечание
В этих примерах StateMachineNumberGuessWorkflow
SequentialNumberGuessWorkflow
FlowchartNumberGuessWorkflow
необходимо заменить Workflow1
или в зависимости от того, какой рабочий процесс выполнен в предыдущем руководстве. Создание рабочего процесса. Если не заменить Workflow1
, то при попытке создать или запустить рабочий процесс будут выданы ошибки сборки.
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()
Этот код создает объект WorkflowApplication, подписывается на три события из жизненного цикла рабочего процесса, начинает рабочий процесс вызовом Run, а затем ждет завершения рабочего процесса. После завершения рабочего процесса устанавливается AutoResetEvent и ведущее приложение завершает работу.
Добавьте следующую инструкцию в начало файла Program.cs или Module1.vb после существующих инструкций using
или Imports
.
Замените строку кода, создающую новое WorkflowApplication , следующим кодом, который создает и передает словарь параметров рабочему процессу, когда процесс создается.
Примечание
Замените Workflow1
в этих примерах на FlowchartNumberGuessWorkflow
, SequentialNumberGuessWorkflow
или StateMachineNumberGuessWorkflow
в зависимости от рабочего процесса, который вы выполнили на предыдущем шаге How to: Create a Workflow . Если не заменить Workflow1
, то при попытке создать или запустить рабочий процесс будут выданы ошибки сборки.
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)
В этом словаре содержится один элемент с ключом MaxNumber
. Ключи в словаре входных данных соответствуют входным аргументам в корневом действии рабочего процесса. MaxNumber
используется рабочим процессом для определения верхней границы случайного числа.
Модифицируйте обработчик Completed , чтобы извлечь и отобразить число ходов, использованных рабочим процессом.
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
Добавьте следующий код в начало метода Main
сразу после существующего объявления AutoResetEvent .
AutoResetEvent idleEvent = new AutoResetEvent(false);
Dim idleEvent As New AutoResetEvent(False)
Добавьте следующий обработчик Idle сразу после трех существующих обработчиков жизненного цикла процесса в Main
.
Idle = delegate (WorkflowApplicationIdleEventArgs e)
{
idleEvent.Set();
}
};
wfApp.Idle =
Sub(e As WorkflowApplicationIdleEventArgs)
idleEvent.Set()
End Sub
Каждый раз, когда рабочий процесс становится неактивным, ожидая следующего предположения, вызывается этот обработчик и idleAction
AutoResetEvent устанавливается. Код на следующем этапе использует idleEvent
и syncEvent
, чтобы определить, ждет рабочий процесс следующего предположения или он завершился.
Примечание
В этом примере ведущее приложение использует события автоматического сброса в обработчиках Completed и Idle , чтобы синхронизировать ведущее приложение с ходом выполнения рабочего процесса. Устанавливать блокировку и ждать неактивности рабочего процесса перед возобновлением закладки не обязательно, но в этом примере требуются события синхронизации, чтобы узел знал, завершен ли рабочий процесс, или он ждет дальнейшего ввода данных от пользователя с помощью Bookmark. Дополнительные сведения см. в разделе "Закладки".
Удалите вызов WaitOne
, замените его кодом для сборки входных данных от пользователя и возобновите Bookmark.
Удалите следующую строку кода.
syncEvent.WaitOne();
syncEvent.WaitOne()
Замените ее следующим примером.
// 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
Щелкните правой кнопкой мыши NumberGuessWorkflowHost в окне Обозреватель решений и выберите команду Установить как запускаемый проект.
Нажмите клавиши CTRL+F5 для сборки и запуска приложения. Попробуйте угадать число с наименьшим числом попыток.
Чтобы протестировать приложение с другим стилем рабочего процесса, замените Workflow1
в коде, который создает WorkflowApplication , на FlowchartNumberGuessWorkflow
, SequentialNumberGuessWorkflow
или StateMachineNumberGuessWorkflow
в зависимости от того, какой стиль рабочего процесса нужен.
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)
Инструкции по добавлению сохраняемости к приложению рабочего процесса см. в следующем разделе How to: Create and Run a Long Running Workflow.
Ниже приведен полный код для метода Main
.
Примечание
Замените Workflow1
в этих примерах на FlowchartNumberGuessWorkflow
, SequentialNumberGuessWorkflow
или StateMachineNumberGuessWorkflow
в зависимости от рабочего процесса, который вы выполнили на предыдущем шаге How to: Create a Workflow . Если не заменить Workflow1
, то при попытке создать или запустить рабочий процесс будут выданы ошибки сборки.
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
Отзыв о .NET
.NET — это проект с открытым исходным кодом. Выберите ссылку, чтобы оставить отзыв:
Обучение
Схема обучения
Добавление логики в консольные приложения C# (начало работы с C#, часть 3) - Training
Развивайте свои навыки работы с логикой C# и операторами итерации, логическими выражениями и блоками кода в этой схеме обучения.