اکتیویتی های مرکب در Workflow

چاپ

نحوه ي ساخت اکتيويتي هاي مرکب در Workflow

در WF4.5، اکتيويتي هاي مرکب زيادي مانند: Sequence و  While و Parallel و ... وجود دارد. آيا روشي براي ساخت يک اکتيويتيِ سفارشيِ مرکب وجود دارد؟ جواب اين سوال بله است.

در اين قسمت از آموزش Workflow، با ارثبري از کلاس NativeActivity، اکتيويتي سفارشي MySequence را خواهيم ساخت.


مراحل پياده سازي سيستم گردش فرم

 پروژه گردش کار GetTestMySequenceWF شامل مراحل زير است:

  1. اضافه کردن فايل MySequence.cs
  2. نوشتن کدهاي لازم براي تست اکتويتي MySquence
  3. اجراي Workflow
  4. پروژه ي گردش کار GetTestMySequenceWF چگونه عمل مي کند؟

اضافه کردن فايل MySquence.cs

در پروژه ActivityLibrary، يک فايل جديد با نام MySquence.cs ايجاد نماييد و کدهاي زير را در آن قرار دهيد:

MySquence.cs

using System.Activities;
using System.Collections.ObjectModel;
namespace ActivityLibrary
{
    public class MySequence : NativeActivity
    {
        public Collection Activities { get; set; }
        public MySequence()
        {
            Activities = new Collection();
        }
        int activityCounter = 0;
        protected override void CacheMetadata(NativeActivityMetadata metadata)
        {
            foreach (var activity in Activities)
            {
                metadata.AddImplementationChild(activity);
            }
        }
        protected override void Execute(NativeActivityContext context)
        {
            ScheduleActivities(context);
        }
        void ScheduleActivities(NativeActivityContext context)
        {
            if (activityCounter < Activities.Count)
                context.ScheduleActivity(this.Activities[activityCounter++], OnActivityCompleted);
        }
        void OnActivityCompleted(NativeActivityContext context, ActivityInstance completedInstance)
        {
            ScheduleActivities(context);
        }
    }
}

 حالا براي اينکه بتوانيد از اکتيويتي MySquence استفاده کنيد، پروژه را Build نماييد.


نوشتن کدهاي لازم براي تست اکتويتي MySquence 

در پروژه WorkflowConsoleApp فايل Program.cs را باز کنيد و متد GetTestMySequenceWF را به آن اضافه نماييد: 

Program.cs

        static Activity GetTestMySquenceWF()
        {
            return new ActivityLibrary.MySequence()
            {
                Activities ={
                    new WriteLine(){Text="WriteLine1"},
                    new WriteLine(){Text="WriteLine2"},
                    new WriteLine(){Text="WriteLine3"}
                }
            };
        }

اجراي Workflow

براي اجراي Workflow، متد Main در فايل Program.cs را بصورت زير تغيير داده و دکمه هاي ميانبر Ctrl+F5 را فشار دهيد:

Program.cs

WorkflowInvoker.Invoke(GetTestMySquenceWF());

خروجي برنامه:


پروژه ي گردش کار GetTestMySequenceWF چگونه عمل مي کند؟

اولين و مهمترين چيز در ايجاد اکتيويتي هاي مرکب اين است که براي ساخت آنها بايد از کلاس NativeActivity يا Activity ارثبري کنيم. بعنوان مثال ما نمي توانيم يک اکتويتي مرکب با ارثبري از کلاس CodeActivity ايجاد کنيم.

با استفاده از شيء MetaData مي توانيم اطلاعات Workflow را ذخيره کنيم. با دسترسي به MetaData سيستم گردش کار از اکتيويتي ها، متغيرها و آرگومانهاي استفاده شده، مطلع مي شود. بنابراين با Override کردن متد CacheMetaData مي توانيم اکتيويتي هاي دلخواه مان را به MetaData اضافه کنيم.

MySquence.cs

        protected override void CacheMetadata(NativeActivityMetadata metadata)
        {
            foreach (var activity in Activities)
            {
                metadata.AddImplementationChild(activity);
            }
        }

داخل متد Execute، متد ScheduleActivities را فراخواني مي کنيم. در واقع با کمک متد ScheduleActivities مي توانيم نحوه ي رفتار اکتيويتي ها هنگام اجرا را مشخص کنيم.

آيا مي توان با استفاده از کد زير، مي توان زمانبندي اجراي اکتويتي ها را تغيير داد؟

MySquence.cs

void ScheduleActivities(NativeActivityContext context)
        {
            //if (activityCounter < Activities.Count)
                //context.ScheduleActivity(this.Activities[activityCounter++], OnActivityCompleted);
            for (int i = 0; i < Activities.Count; i++)
            {
                context.ScheduleActivity(this.Activities[i]);
            }
        }

خوب، جواب بله است. ما مي توانيم با اين روش اکتيوتي ها را زمانبندي (schedule) کنيم، اما همان طور که در تصوير زير مشاهده مي کنيد، بعد از تغيير متد ScheduleActivities، ترتيب اجراي اکتيويتي ها برعکس شده است:

اين اتفاق بخاطر اين است که Workflow بصورت runtime اکتيويتي ها را در Stack ذخيره مي کند و اکتيويتي اي که در اول صف قرار دارد، در آخر اجرا خواهد شد.