Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Начиная с .NET Framework 4.5 выражения C# поддерживаются в Windows Workflow Foundation (WF). Новые проекты рабочих процессов C#, созданные в Visual Studio 2012, предназначенные для .NET Framework 4.5, используют выражения C# и проекты рабочих процессов Visual Basic используют выражения Visual Basic. Существующие проекты рабочих процессов .NET Framework 4, использующие выражения Visual Basic, можно перенести в .NET Framework 4.6.1 независимо от языка проекта и поддерживаются. В этом разделе представлен обзор выражений C# в WF.
Использование выражений C# в рабочих процессах
Использование выражений C# в конструкторе рабочих процессов
Начиная с .NET Framework 4.5 выражения C# поддерживаются в Windows Workflow Foundation (WF). Проекты рабочих процессов C#, созданные в Visual Studio 2012, предназначенные для .NET Framework 4.5, используют выражения C#, а проекты рабочих процессов Visual Basic используют выражения Visual Basic. Чтобы указать требуемое выражение C#, введите его в поле с меткой ВВОД выражения C#. Эта метка отображается в окне свойств, когда действие выбрано в конструкторе, или на действии в конструкторе рабочих процессов. В следующем примере два WriteLine действия содержатся внутри Sequence и NoPersistScope.
Замечание
Выражения C# поддерживаются только в Visual Studio и не поддерживаются в повторно размещенном конструкторе рабочих процессов. Дополнительные сведения о новых функциях WF45, поддерживаемых в повторно размещенном конструкторе, см. в разделе "Поддержка новых функций Workflow Foundation 4.5" в конструкторе повторно размещенных рабочих процессов.
Обратная совместимость
Поддерживаются выражения Visual Basic в существующих проектах рабочих процессов .NET Framework 4 C#, перенесенных в .NET Framework 4.6.1. При просмотре выражений Visual Basic в конструкторе рабочих процессов текст существующего выражения Visual Basic заменяется на Значение задано в XAML, если выражение Visual Basic не соответствует допустимому синтаксису C#. Если выражение Visual Basic является допустимым синтаксисом C#, отображается выражение. Чтобы обновить выражения Visual Basic на C#, их можно изменить в конструкторе рабочих процессов и указать эквивалентное выражение C#. Для обновления выражений Visual Basic до C# не требуется, но после обновления выражений в конструкторе рабочих процессов они преобразуются в C# и не могут быть возвращены в Visual Basic.
Использование выражений C# в рабочих процессах кода
Выражения C# поддерживаются в рабочих процессах на основе кода .NET Framework 4.6.1, но перед вызовом рабочего процесса выражения C# необходимо скомпилировать с помощью TextExpressionCompiler.Compile. Авторы рабочих процессов могут использовать CSharpValue для представления r-значения выражения и CSharpReference представления l-значения выражения. В следующем примере создается рабочий процесс с действием Assign, а действие WriteLine содержится в действии Sequence. Указан CSharpReference для аргумента To в Assign, и он представляет l-значение выражения. Для CSharpValue аргумента Value и для Assign аргумента Text указано значение WriteLine, которое представляет r-значение для этих двух выражений.
Variable<int> n = new Variable<int>
{
Name = "n"
};
Activity wf = new Sequence
{
Variables = { n },
Activities =
{
new Assign<int>
{
To = new CSharpReference<int>("n"),
Value = new CSharpValue<int>("new Random().Next(1, 101)")
},
new WriteLine
{
Text = new CSharpValue<string>("\"The number is \" + n")
}
}
};
CompileExpressions(wf);
WorkflowInvoker.Invoke(wf);
После создания рабочего процесса выражения C# компилируются путем вызова вспомогательного CompileExpressions метода, а затем вызывается рабочий процесс. В следующем примере используется CompileExpressions метод.
static void CompileExpressions(Activity activity)
{
// activityName is the Namespace.Type of the activity that contains the
// C# expressions.
string activityName = activity.GetType().ToString();
// Split activityName into Namespace and Type.Append _CompiledExpressionRoot to the type name
// to represent the new type that represents the compiled expressions.
// Take everything after the last . for the type name.
string activityType = activityName.Split('.').Last() + "_CompiledExpressionRoot";
// Take everything before the last . for the namespace.
string activityNamespace = string.Join(".", activityName.Split('.').Reverse().Skip(1).Reverse());
// Create a TextExpressionCompilerSettings.
TextExpressionCompilerSettings settings = new TextExpressionCompilerSettings
{
Activity = activity,
Language = "C#",
ActivityName = activityType,
ActivityNamespace = activityNamespace,
RootNamespace = null,
GenerateAsPartialClass = false,
AlwaysGenerateSource = true,
ForImplementation = false
};
// Compile the C# expression.
TextExpressionCompilerResults results =
new TextExpressionCompiler(settings).Compile();
// Any compilation errors are contained in the CompilerMessages.
if (results.HasErrors)
{
throw new Exception("Compilation failed.");
}
// Create an instance of the new compiled expression type.
ICompiledExpressionRoot compiledExpressionRoot =
Activator.CreateInstance(results.ResultType,
new object[] { activity }) as ICompiledExpressionRoot;
// Attach it to the activity.
CompiledExpressionInvoker.SetCompiledExpressionRoot(
activity, compiledExpressionRoot);
}
Замечание
Если выражения C# не компилируются, NotSupportedException создается при вызове рабочего процесса с сообщением, аналогичным следующему: Expression Activity type 'CSharpValue1' требует компиляции для выполнения. Убедитесь, что рабочий процесс скомпилирован.
Если ваш рабочий процесс на основе пользовательского кода использует DynamicActivity, то в методе CompileExpressions требуются некоторые изменения, как показано в следующем примере кода.
static void CompileExpressions(DynamicActivity dynamicActivity)
{
// activityName is the Namespace.Type of the activity that contains the
// C# expressions. For Dynamic Activities this can be retrieved using the
// name property , which must be in the form Namespace.Type.
string activityName = dynamicActivity.Name;
// Split activityName into Namespace and Type.Append _CompiledExpressionRoot to the type name
// to represent the new type that represents the compiled expressions.
// Take everything after the last . for the type name.
string activityType = activityName.Split('.').Last() + "_CompiledExpressionRoot";
// Take everything before the last . for the namespace.
string activityNamespace = string.Join(".", activityName.Split('.').Reverse().Skip(1).Reverse());
// Create a TextExpressionCompilerSettings.
TextExpressionCompilerSettings settings = new TextExpressionCompilerSettings
{
Activity = dynamicActivity,
Language = "C#",
ActivityName = activityType,
ActivityNamespace = activityNamespace,
RootNamespace = null,
GenerateAsPartialClass = false,
AlwaysGenerateSource = true,
ForImplementation = true
};
// Compile the C# expression.
TextExpressionCompilerResults results =
new TextExpressionCompiler(settings).Compile();
// Any compilation errors are contained in the CompilerMessages.
if (results.HasErrors)
{
throw new Exception("Compilation failed.");
}
// Create an instance of the new compiled expression type.
ICompiledExpressionRoot compiledExpressionRoot =
Activator.CreateInstance(results.ResultType,
new object[] { dynamicActivity }) as ICompiledExpressionRoot;
// Attach it to the activity.
CompiledExpressionInvoker.SetCompiledExpressionRootForImplementation(
dynamicActivity, compiledExpressionRoot);
}
Существует несколько различий в перегрузке CompileExpressions , которая компилирует выражения C# в динамическом действии.
Параметр для
CompileExpressionsявляетсяDynamicActivity.Имя типа и пространство имен извлекаются с помощью
DynamicActivity.Nameсвойства.TextExpressionCompilerSettings.ForImplementationзадан какtrue.CompiledExpressionInvoker.SetCompiledExpressionRootForImplementationвызывается вместоCompiledExpressionInvoker.SetCompiledExpressionRoot.
Дополнительные сведения о работе с выражениями в коде см. в статье "Создание рабочих процессов, действий и выражений с помощью императивного кода".
Использование выражений C# в рабочих процессах XAML
Выражения C# поддерживаются в рабочих процессах XAML. Скомпилированные рабочие процессы XAML компилируются в тип, и свободные рабочие процессы XAML загружаются средой выполнения и компилируются в дерево действий при выполнении рабочего процесса.
Скомпилированный Xaml
Выражения C# поддерживаются в скомпилированных рабочих процессах XAML, скомпилированных в тип в рамках проекта рабочего процесса C#, предназначенного для .NET Framework 4.6.1. Скомпилированный XAML — это тип разработки рабочих процессов по умолчанию в Visual Studio, а проекты рабочих процессов C#, созданные в Visual Studio, предназначенные для .NET Framework 4.6.1, используют выражения C#.
Динамический XAML
Выражения C# поддерживаются в свободных рабочих процессах XAML. Программа хоста рабочего процесса, загружающая и вызывающая свободный рабочий процесс XAML, должна быть нацелена на .NET Framework 4.6.1, и CompileExpressions должно быть установлено в true (по умолчанию false). Чтобы задать CompileExpressions на true, создайте экземпляр ActivityXamlServicesSettings с установленным свойством CompileExpressions на true и передайте его в качестве параметра ActivityXamlServices.Load. Если CompileExpressions не установлено в true, будет выброшен NotSupportedException с сообщением, аналогичным следующему: Expression Activity type 'CSharpValue1' требует компиляции для выполнения. Убедитесь, что рабочий процесс скомпилирован.
ActivityXamlServicesSettings settings = new ActivityXamlServicesSettings
{
CompileExpressions = true
};
DynamicActivity<int> wf = ActivityXamlServices.Load(new StringReader(serializedAB), settings) as DynamicActivity<int>;
Дополнительные сведения о работе с рабочими процессами XAML см. в статье сериализация рабочих процессов и действий в XAML и из нее.
Использование выражений C# в службах рабочих процессов XAMLX
Выражения C# поддерживаются в службах рабочих процессов XAMLX. Если служба рабочего процесса размещена в службах IIS или WAS, то никаких дополнительных шагов не требуется, но если служба рабочего процесса XAML размещена самостоятельно, необходимо скомпилировать выражения C#. Чтобы скомпилировать выражения C# в автономной службе рабочих процессов XAMLX, сначала загрузите XAMLX-файл в WorkflowService, а затем передайте метод Body в WorkflowServiceCompileExpressions, описанный в предыдущем разделе "Использование выражений C# в рабочих процессах кода". В следующем примере загружается служба рабочего процесса XAMLX, выражения C# компилируются, а затем служба рабочего процесса открывается и ожидает запросов.
// Load the XAMLX workflow service.
WorkflowService workflow1 =
(WorkflowService)XamlServices.Load(xamlxPath);
// Compile the C# expressions in the workflow by passing the Body to CompileExpressions.
CompileExpressions(workflow1.Body);
// Initialize the WorkflowServiceHost.
var host = new WorkflowServiceHost(workflow1, new Uri("http://localhost:8293/Service1.xamlx"));
// Enable Metadata publishing/
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
// Open the WorkflowServiceHost and wait for requests.
host.Open();
Console.WriteLine("Press enter to quit");
Console.ReadLine();
Если выражения C# не компилируются, операция Open выполняется успешно, но рабочий процесс завершится ошибкой при вызове.
CompileExpressions Следующий метод совпадает с методом из предыдущего раздела Использование C# в разделах рабочих процессов кода.
static void CompileExpressions(Activity activity)
{
// activityName is the Namespace.Type of the activity that contains the
// C# expressions.
string activityName = activity.GetType().ToString();
// Split activityName into Namespace and Type.Append _CompiledExpressionRoot to the type name
// to represent the new type that represents the compiled expressions.
// Take everything after the last . for the type name.
string activityType = activityName.Split('.').Last() + "_CompiledExpressionRoot";
// Take everything before the last . for the namespace.
string activityNamespace = string.Join(".", activityName.Split('.').Reverse().Skip(1).Reverse());
// Create a TextExpressionCompilerSettings.
TextExpressionCompilerSettings settings = new TextExpressionCompilerSettings
{
Activity = activity,
Language = "C#",
ActivityName = activityType,
ActivityNamespace = activityNamespace,
RootNamespace = null,
GenerateAsPartialClass = false,
AlwaysGenerateSource = true,
ForImplementation = false
};
// Compile the C# expression.
TextExpressionCompilerResults results =
new TextExpressionCompiler(settings).Compile();
// Any compilation errors are contained in the CompilerMessages.
if (results.HasErrors)
{
throw new Exception("Compilation failed.");
}
// Create an instance of the new compiled expression type.
ICompiledExpressionRoot compiledExpressionRoot =
Activator.CreateInstance(results.ResultType,
new object[] { activity }) as ICompiledExpressionRoot;
// Attach it to the activity.
CompiledExpressionInvoker.SetCompiledExpressionRoot(
activity, compiledExpressionRoot);
}