C#-uttryck
Från och med .NET Framework 4.5 stöds C#-uttryck i Windows Workflow Foundation (WF). Nya C#-arbetsflödesprojekt som skapats i Visual Studio 2012 och som är mål för .NET Framework 4.5 använder C#-uttryck och Visual Basic-arbetsflödesprojekt använder Visual Basic-uttryck. Befintliga .NET Framework 4-arbetsflödesprojekt som använder Visual Basic-uttryck kan migreras till .NET Framework 4.6.1 oavsett projektspråk och stöds. Det här avsnittet innehåller en översikt över C#-uttryck i WF.
Använda C#-uttryck i arbetsflöden
Använda C#-uttryck i arbetsflödesdesignern
Från och med .NET Framework 4.5 stöds C#-uttryck i Windows Workflow Foundation (WF). C#-arbetsflödesprojekt som skapats i Visual Studio 2012 och som riktar sig mot .NET Framework 4.5 använder C#-uttryck, medan Visual Basic-arbetsflödesprojekt använder Visual Basic-uttryck. Om du vill ange önskat C#-uttryck skriver du det i rutan med etiketten Ange ett C#-uttryck. Den här etiketten visas i egenskapsfönstret när aktiviteten väljs i designern eller på aktiviteten i arbetsflödesdesignern. I följande exempel finns två WriteLine
aktiviteter i en Sequence
i en NoPersistScope
.
Kommentar
C#-uttryck stöds endast i Visual Studio och stöds inte i den nya arbetsflödesdesignern. Mer information om nya WF45-funktioner som stöds i den omvärdade designern finns i Stöd för nya Workflow Foundation 4.5-funktioner i arbetsflödesdesignern med nytt värd.
Bakåtkompatibilitet
Visual Basic-uttryck i befintliga .NET Framework 4 C#-arbetsflödesprojekt som har migrerats till .NET Framework 4.6.1 stöds. När Visual Basic-uttrycken visas i arbetsflödesdesignern ersätts texten i det befintliga Visual Basic-uttrycket med Värde i XAML, såvida inte Visual Basic-uttrycket är giltig C#-syntax. Om Visual Basic-uttrycket är giltig C#-syntax visas uttrycket. Om du vill uppdatera Visual Basic-uttrycken till C# kan du redigera dem i arbetsflödesdesignern och ange motsvarande C#-uttryck. Det krävs inte att du uppdaterar Visual Basic-uttrycken till C#, men när uttrycken har uppdaterats i arbetsflödesdesignern konverteras de till C# och kan inte återställas till Visual Basic.
Använda C#-uttryck i kodarbetsflöden
C#-uttryck stöds i .NET Framework 4.6.1-kodbaserade arbetsflöden, men innan arbetsflödet kan anropas måste C#-uttrycken kompileras med .TextExpressionCompiler.Compile Arbetsflödesförfattare kan använda CSharpValue
för att representera r-värdet för ett uttryck och CSharpReference
för att representera l-värdet för ett uttryck. I följande exempel skapas ett arbetsflöde med en Assign
aktivitet och en WriteLine
aktivitet som ingår i en Sequence
aktivitet. A CSharpReference
anges för To
argumentet Assign
i och representerar uttryckets l-värde. A CSharpValue
anges för Value
argumentet Assign
för , och för argumentet WriteLine
för Text
, och representerar r-värdet för dessa två uttryck.
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);
När arbetsflödet har konstruerats kompileras C#-uttrycken CompileExpressions
genom att anropa hjälpmetoden och sedan anropas arbetsflödet. Följande exempel är CompileExpressions
metoden.
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);
}
Kommentar
Om C#-uttrycken inte kompileras utlöses ett NotSupportedException när arbetsflödet anropas med ett meddelande som liknar följande: Expression Activity type 'CSharpValue
1' kräver kompilering för att kunna köras. Kontrollera att arbetsflödet har kompilerats."
Om ditt anpassade kodbaserade arbetsflöde använder DynamicActivity
krävs vissa ändringar av CompileExpressions
metoden, vilket visas i följande kodexempel.
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);
}
Det finns flera skillnader i överbelastningen CompileExpressions
som kompilerar C#-uttrycken i en dynamisk aktivitet.
Parametern till
CompileExpressions
är enDynamicActivity
.Typnamnet och namnområdet hämtas med hjälp av
DynamicActivity.Name
egenskapen .TextExpressionCompilerSettings.ForImplementation
är inställt påtrue
.CompiledExpressionInvoker.SetCompiledExpressionRootForImplementation
anropas i ställetCompiledExpressionInvoker.SetCompiledExpressionRoot
för .
Mer information om hur du arbetar med uttryck i kod finns i Redigera arbetsflöden, aktiviteter och uttryck med imperativ kod.
Använda C#-uttryck i XAML-arbetsflöden
C#-uttryck stöds i XAML-arbetsflöden. Kompilerade XAML-arbetsflöden kompileras till en typ och lösa XAML-arbetsflöden läses in av körningen och kompileras till ett aktivitetsträd när arbetsflödet körs.
Kompilerad Xaml
C#-uttryck stöds i kompilerade XAML-arbetsflöden som kompileras till en typ som en del av ett C#-arbetsflödesprojekt som riktar sig till .NET Framework 4.6.1. Kompilerad XAML är standardtypen för arbetsflödesredigering i Visual Studio, och C#-arbetsflödesprojekt som skapats i Visual Studio som är mål för .NET Framework 4.6.1 använder C#-uttryck.
Lös Xaml
C#-uttryck stöds i lösa XAML-arbetsflöden. Arbetsflödets värdprogram som läser in och anropar det lösa XAML-arbetsflödet måste ha .NET Framework 4.6.1 som mål och CompileExpressions måste anges till true
(standardvärdet är false
). Om du vill ange CompileExpressions till true
skapar du en ActivityXamlServicesSettings instans med dess CompileExpressions egenskap inställd på true
och skickar den som en parameter till ActivityXamlServices.Load. Om CompileExpressions
Är inte inställt på true
genereras ett NotSupportedException med ett meddelande som liknar följande: Expression Activity type 'CSharpValue
1' kräver kompilering för att kunna köras. Kontrollera att arbetsflödet har kompilerats."
ActivityXamlServicesSettings settings = new ActivityXamlServicesSettings
{
CompileExpressions = true
};
DynamicActivity<int> wf = ActivityXamlServices.Load(new StringReader(serializedAB), settings) as DynamicActivity<int>;
Mer information om hur du arbetar med XAML-arbetsflöden finns i Serialisera arbetsflöden och aktiviteter till och från XAML.
Använda C#-uttryck i XAMLX-arbetsflödestjänster
C#-uttryck stöds i XAMLX-arbetsflödestjänster. När en arbetsflödestjänst finns i IIS eller WAS krävs inga ytterligare steg, men om XAML-arbetsflödestjänsten är lokalt installerad måste C#-uttrycken kompileras. Om du vill kompilera C#-uttrycken i en XAMLX-arbetsflödestjänst med egen värd läser du först in XAMLX-filen i en WorkflowService
och skickar Body
sedan till WorkflowService
metoden CompileExpressions
som beskrivs i föregående avsnitt Använda C#-uttryck i kodarbetsflöden . I följande exempel läses en XAMLX-arbetsflödestjänst in, C#-uttryck kompileras och sedan öppnas arbetsflödestjänsten och väntar på begäranden.
// 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();
Om C#-uttrycken inte kompileras lyckas åtgärden, Open
men arbetsflödet misslyckas när det anropas. Följande CompileExpressions
metod är samma som metoden från föregående avsnitt Använda C#-uttryck i kodarbetsflöden .
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);
}