Proprietà di esecuzione del flusso di lavoro

Tramite l'archiviazione thread-local (TLS), CLR gestisce un contesto di esecuzione per ogni thread. Questo contesto di esecuzione determina le proprietà note dei thread quali l'identità del thread, la transazione di ambiente e il set di autorizzazioni corrente oltre alle proprietà del thread definite dall'utente come gli slot denominati.

A differenza dei programmi destinati direttamente a CLR, i programmi del flusso di lavoro sono alberi di attività con ambiti gerarchici che vengono eseguite in un ambiente indipendente dal thread. Pertanto i meccanismi TLS standard non possono essere usati direttamente per determinare il contesto incluso nell'ambito per un elemento di lavoro specificato. Ad esempio, due rami paralleli di esecuzione potrebbero usare transazioni diverse, oppure il servizio di pianificazione potrebbe eseguire l'interfoliazione dell'esecuzione sullo stesso thread CLR.

Le proprietà di esecuzione del flusso di lavoro forniscono un meccanismo per aggiungere proprietà specifiche del contesto all'ambiente di un'attività. In questo modo un'attività può dichiarare quali proprietà sono incluse nell'ambito per i relativi sottoalberi e inoltre fornire hook per impostare e chiudere TLS al fine di interoperare correttamente con gli oggetti CLR.

Creazione e utilizzo di proprietà di esecuzione del flusso di lavoro

Le proprietà di esecuzione del flusso di lavoro in genere implementano l'interfaccia di IExecutionProperty, anche se le proprietà incentrate sulla messaggistica possono implementare invece ISendMessageCallback e IReceiveMessageCallback. Per creare una proprietà di esecuzione del flusso di lavoro, creare una classe che implementa l'interfaccia IExecutionProperty e implementare i membri SetupWorkflowThread e CleanupWorkflowThread. Questi membri forniscono la proprietà di esecuzione e consentono di impostare e chiudere correttamente l'archivio locale del thread durante ogni impulso di lavoro dell'attività che contiene la proprietà, incluse eventuali attività figlio. In questo esempio viene creato un oggetto ConsoleColorProperty che imposta l'oggetto Console.ForegroundColor.

class ConsoleColorProperty : IExecutionProperty  
{  
    public const string Name = "ConsoleColorProperty";  
  
    ConsoleColor original;  
    ConsoleColor color;  
  
    public ConsoleColorProperty(ConsoleColor color)  
    {  
        this.color = color;  
    }  
  
    void IExecutionProperty.SetupWorkflowThread()  
    {  
        original = Console.ForegroundColor;  
        Console.ForegroundColor = color;  
    }  
  
    void IExecutionProperty.CleanupWorkflowThread()  
    {  
        Console.ForegroundColor = original;  
    }  
}  

Gli autori di attività possono usare questa proprietà registrandola nell'override di esecuzione dell'attività. In questo esempio viene definita un'attività ConsoleColorScope che registra l'oggetto ConsoleColorProperty aggiungendolo alla raccolta Properties dell'oggetto NativeActivityContext corrente.

public sealed class ConsoleColorScope : NativeActivity  
{  
    public ConsoleColorScope()  
        : base()  
    {  
    }  
  
    public ConsoleColor Color { get; set; }  
    public Activity Body { get; set; }  
  
    protected override void Execute(NativeActivityContext context)  
    {  
        context.Properties.Add(ConsoleColorProperty.Name, new ConsoleColorProperty(this.Color));  
  
        if (this.Body != null)  
        {  
            context.ScheduleActivity(this.Body);  
        }  
    }  
}  

Quando il corpo dell'attività inizia un impulso di lavoro, viene chiamato il metodo SetupWorkflowThread della proprietà e quando l'impulso di lavoro viene completato, viene chiamato il metodo CleanupWorkflowThread. In questo esempio viene creato un flusso di lavoro che usa un'attività Parallel con tre rami. I primi due rami, a differenza del terzo, usano l'attività ConsoleColorScope. Tutti i tre rami contengono due attività WriteLine e un'attività Delay. Quando l'attività Parallel viene eseguita, le attività contenute nei rami vengono eseguite in un modo caratterizzato da interfoliazione, ma quando ogni attività figlio viene eseguita, l'oggetto ConsoleColorProperty applica il corretto colore della console.

Activity wf = new Parallel  
{  
    Branches =
    {  
        new ConsoleColorScope  
        {  
            Color = ConsoleColor.Blue,  
            Body = new Sequence  
            {  
                Activities =
                {  
                    new WriteLine  
                    {  
                        Text = "Start blue text."  
                    },  
                    new Delay  
                    {  
                        Duration = TimeSpan.FromSeconds(1)  
                    },  
                    new WriteLine  
                    {  
                        Text = "End blue text."  
                    }  
                }  
            }  
        },  
        new ConsoleColorScope  
        {  
            Color = ConsoleColor.Red,  
            Body = new Sequence  
            {  
                Activities =
                {  
                    new WriteLine  
                    {  
                        Text = "Start red text."  
                    },  
                    new Delay  
                    {  
                        Duration = TimeSpan.FromSeconds(1)  
                    },  
                    new WriteLine  
                    {  
                        Text = "End red text."  
                    }  
                }  
            }  
        },  
        new Sequence  
        {  
            Activities =
            {  
                new WriteLine  
                {  
                    Text = "Start default text."  
                },  
                new Delay  
                {  
                    Duration = TimeSpan.FromSeconds(1)  
                },  
                new WriteLine  
                {  
                    Text = "End default text."  
                }  
            }  
        }  
    }  
};  
  
WorkflowInvoker.Invoke(wf);  

Quando il flusso di lavoro viene richiamato, l'output seguente viene scritto nella finestra della console.

Start blue text.  
Start red text.  
Start default text.  
End blue text.  
End red text.  
End default text.  

Nota

Sebbene non venga mostrata nell'output precedente, ogni riga di testo nella finestra della console viene visualizzata con il colore indicato.

Le proprietà di esecuzione del flusso di lavoro possono essere usate dagli autori di attività personalizzate e consentono di gestire l'handle per attività quali CorrelationScope e TransactionScope.

Vedi anche