這通常是長時間運行的工作流的最小示例,它等待控制檯上的用戶輸入。 (此代碼永遠不會執行,把它作爲唯一的一個例子)
/// Activity that waits on bookmark for
/// someone to send it some text
///
public sealed class ReadLine: NativeActivity<string>
{
[RequiredArgument]
public InArgument<string> BookmarkName { get; set; }
protected override bool CanInduceIdle
{
get
{
return true;
}
}
protected override void Execute(NativeActivityContext context)
{
context.CreateBookmark(
BookmarkName.Get(context),
new BookmarkCallback(OnReadComplete));
}
void OnReadComplete(NativeActivityContext context, Bookmark bookmark, object state)
{
context.SetValue(base.Result, state as string);
}
}
/// Program that uses ReadLine activity's bookmark to persist
/// workflow and waits for user input to resume it
///
public class Program
{
static InstanceStore InstanceStore;
static Activity Activity = GetExampleActivity();
static AutoResetEvent unloadEvent = new AutoResetEvent(false);
static Guid WfId;
static WorkflowApplication WfApp;
const string READ_LINE_BOOKMARK = "ReadLineBookMark";
static void Main()
{
CreateInstanceStore();
CreateWorkflowApp();
// Start workflow application and wait for input
StartAndUnload();
//Get user input and send it to ReadLine bookmark reviving workflow
GetInputAndComplete();
}
static void StartAndUnload()
{
WfApp.Run();
WfId = app.Id;
// !! Workflow will go idle on bookmark, no need to call Unload()
unloadEvent.WaitOne();
}
static void GetInputAndComplete()
{
var input = Console.ReadLine();
// We've the text input, let's resume this thing
WfApp.Load(WfId);
WfApp.ResumeBookmark(READ_LINE_BOOKMARK, input);
unloadEvent.WaitOne();
}
static void CreateInstanceStore()
{
InstanceStore = new SqlWorkflowInstanceStore("connection string");
var handle = InstanceStore.CreateInstanceHandle();
var view = InstanceStore.Execute(
handle,
new CreateWorkflowOwnerCommand(),
TimeSpan.FromSeconds(5));
handle.Free();
InstanceStore.DefaultInstanceOwner = view.InstanceOwner;
}
static void CreateWorkflowApp()
{
WfApp = new WorkflowApplication(Activity)
{
InstanceStore = InstanceStore,
};
WfApp.PersistableIdle = (e) => { return PersistableIdleAction.Unload; }
WfApp.Unloaded = (e) =>
{
Console.WriteLine("WF App Unloaded\n");
unloadEvent.Set();
};
WfApp.Completed = (e) =>
{
Console.WriteLine("\nWF App Ended: {0}.", e.CompletionState);
};
}
static Activity GetExampleActivity()
{
var response = new Variable<string>();
return return new Sequence()
{
Variables = { response },
Activities =
{
new WriteLine()
{
Text = new InArgument<string>("Type some word:")
},
new ReadLine()
{
BookmarkName = READ_LINE_BOOKMARK,
Result = new OutArgument<string>(response)
},
new WriteLine()
{
Text = new InArgument<string>((context) => "You've typed: " + response.Get(context))
}
}
};
}
話雖這麼說,請考慮使用IIS和AppFabric的,你會不會後悔。 AppFabric有六次點擊,在WF中實現了兩個必須要做的痛苦事情:持久性和監控。如果您選擇此路徑,您不會永遠不需要編寫代碼。
將您的工作流程部署爲WCF應用程序,並將其作爲任何其他WCF合同進行調用。你有OperationContracts這是接收活動(那些誰等待並堅持,如果它需要太長時間)和相應的發送活動(誰返回給客戶端)。你甚至有他們之間的相關性的概念。AppFabric負責恢復工作流,只是傳遞一個先前初始化的相關句柄。
AppFabric爲您提供了一個配置用戶界面來配置持久性存儲,監控和其他選項,如閒置和/或保持之前的時間。
您可以直觀的有功/無/暫停工作流程,監測數據,等等,等等
有沒有什麼不能承載這些工作流程爲通過IIS服務的一個原因? –
Mike: 謝謝。你會怎麼看?我會得到什麼好處?這可能是一種可能性,我不明白爲什麼,但另一方面,我也不明白爲什麼。 :-) –