创建一个新的宿主应用程序_第1页
创建一个新的宿主应用程序_第2页
创建一个新的宿主应用程序_第3页
创建一个新的宿主应用程序_第4页
创建一个新的宿主应用程序_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、创建一个新的宿主应用程序1.就像你在前一章做的一样,打开Visual Studio创建一个新应用程序项目。但是,不是要创建一个基于控制台的应用程序,而是创建一个Windows应用程序,名称为WorkflowPersister。下面的步骤在第二章中已经描述过:包含“添加工作流assembly引用”、“宿主工作流运行时”、“创建WorkflowRuntime工厂对象”,“启动工作流运行时”,“停止工作流运行时”,“使用工作流运行时工厂对象”,“处理工作流运行时事件”过程。最后,添加一个app.config文件(可参考前一章中的“添加SqlTrackingService到你的工作流中”,可不要忘记添

2、加System.Configuration的引用)。2.现在向app.config文件中添加恰当的数据库连接字符串(数据库为WorkflowStore)。<?xml version="1.0" encoding="utf-8" ?><configuration><connectionStrings><add name="StorageDatabase" connectionString="Data Source=(local)SQLEXPRESS;Initial Catalog=Wo

3、rkflowStore;Integrated Security=True;"/></connectionStrings></configuration>3.当你创建了WorkflowPersister项目时,Visual Studio显示了Windows Forms视图设计器。在Windows Forms视图设计器中把鼠标移到工具箱上,选择一个Button控件,并把它拖放到设计器的界面上。4.我们将为这个按钮设置一些富有意义的文字属性,以便于我们知道我们点击的是什么。选中这个按钮,然后在Visual Studio的属性面板中选择该按钮的Text属性,把该

4、属性的值设置为“Start Workflow”。5.为该按钮添加Click事件的处理程序,具体代码将在后面的步骤中添加。6.修改按钮的位置和大小,如下图所示:7.重复步骤3至步骤5,再添加两个按钮,一个的text属性为“Unload Workflow”,另一个的text属性为“Load Workflow”。如下图所示:8.现在就为测试我们的工作流创建好了用户界面,该是为我们将执行的应用程序添加事件处理代码的时候了。当应用程序加载时我们需要初始化一些东西,做这些工作的一个很合适的地方是在主应用程序窗体中的Load事件处理程序。9.在该事件处理程序(处理方法)中输入下面的代码: _runtime

5、= WorkflowFactory.GetWorkflowRuntime();_runtime.WorkflowCompleted +=new EventHandler<WorkflowCompletedEventArgs>(Runtime_WorkflowCompleted);_runtime.WorkflowTerminated +=new EventHandler<WorkflowTerminatedEventArgs>(Runtime_WorkflowTerminated);10。在Form1类中声明下面名称为_runtime的字段:protected Work

6、flowRuntime _runtime = null;protected WorkflowInstance _instance = null;11.添加、和三个工作流组件的引用(可参考前面章节),然后在该代码文件中添加下面的命名空间:using System.Workflow.Runtime;12.尽管我们现在有了一个应用程序来宿主工作流运行时,但它实际上没做任何事。为完成些功能,我们需向按钮的事件处理中添加一些代码。先向button1_Click中添加下面的代码:button2.Enabled = true;button1.Enabled = false;_instance = _runt

7、ime.CreateWorkflow(typeof(PersistedWorkflow.Workflow1);_instance.Start();这些代码使“Start Workflow”按钮禁用,而让“Unload Workflow”按钮可用,然后启动了一个新的工作流实例。13.下一步,找到“Unload WorkflowInstance”按钮的事件处理:button2_Click,然后添加下面的代码。这里,我们使用WorkflowInstance.Unload方法来卸载工作流实例并把它写入数据库。在工作流实例卸载后,我们让“Load Workflow”按钮可用。注意假如我们在卸载工作流实例

8、时产生异常,“Load Workflow”按钮是不可使用的。这样做的意义是:假如卸载请求失败,也就不用再加载。button2.Enabled = false;try_instance.Unload();button3.Enabled = true; / trycatch (Exception ex)MessageBox.Show(String.Format("Exception while unloading workflow" +" instance: '0'",ex.Message); / catch123备注:牢记WorkflowI

9、nstance.Unload是同步的,虽然我在本章前面已经阐述过,但这点很重要。这意味着线程试图卸载工作流实例时将会被阻塞(暂停),直到操作完成后为止(不管卸载实例时是成功还是失败)。在这种情况下,可准确执行我想要的行为(指卸载),因为我不想反复查看实例是否被卸载。但有时,你想在卸载时不会被阻塞,就应使用前面说过的Workflowinstance.TryUnload。稍后,在你添加完最后一批代码并运行应用程序时,当你单击“Unload Workflow”时密切观察,你会看到应用程序会简短地被冻结,因为它正等待工作流卸载。14.现在回到我们关注的工作流事件处理上:Runtime_Workflow

10、Completed和Runtime_WorkflowTerminated。这两个事件处理实际上完成相同的动作,那就是重置应用程序以便为另一个工作流实例的执行做好准备。在“button2”的“click”事件处理方法(该方法包含代码我们已在前面的步骤中添加)的下面添加下面这些方法:void Runtime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)WorkflowCompleted();void Runtime_WorkflowTerminated(object sender, WorkflowTerminated

11、EventArgs e)WorkflowCompleted();15.当然,我们现在还要创建“WorkflowCompleted”方法。假如你熟悉Windows编程,你可能知道Windows一直以来存在着的限制问题。这个限制简单的说就是你不能在创建窗口控件的线程外的任何线程中改变该窗口控件的状态。因此假如你想改变某个控件的text,你必须在创建该控件的同一线程上指定该控件的text,使用任何其它线程最有可能导致的结果是造成你的应用程序崩溃。因此我们即将加入的代码对你来说可能很搞笑,但所有要做的这些的真正目的是确信我们是在原来的创建按钮的线程中来使按钮能用和禁用。(事件处理几乎总是在不同的线程上

12、进行调用。)假如我们只是在按钮自身的事件处理中使其可用,应用程序可能还是能工作,但它更大的可能是崩溃和挂起。简单地把下面的代码复制并放到源文件Form1类的尾部,应用程序才会正确的工作。private delegate void WorkflowCompletedDelegate();private void WorkflowCompleted()if (this.InvokeRequired)/ Wrong thread, so switch to the UI threadWorkflowCompletedDelegate d = delegate() WorkflowCompleted(

13、); ;this.Invoke(d); / ifelsebutton1.Enabled = true;button2.Enabled = false;button3.Enabled = false; / else16.在创建我们将执行的工作流之前我们需要最后做一件事,那就是要修改WorkflowFactory类。假如你从第五章(“为你的工作流添加跟踪服务”)以来准确地遵循了所有的步骤来创建和修改WorkflowFactory的话,你实际上创建了一个为工作流运行时提供跟踪服务的工厂对象。我们将对该代码进行轻微的调整,把SqlTrackingService服务改为SqlWorkingPersist

14、enceService,并且改变声明命名空间的语句(把改为)。打开WorkflowFactory.cs文件进行编辑。17.用下面的代码来替换声明的命名空间。using System.Workflow.Runtime.Hosting;using System.Configuration;18。最后为运行时添加持久化服务,方法是在创建工作流运行时对象后添加下面的代码:string conn = ConfigurationManager.ConnectionStrings"StorageDatabase".ConnectionString;_workflowRuntime.Add

15、Service(new SqlWorkflowPersistenceService(conn);注意:因为我们在代码中创建的工作流实例的类型是PersistedWorkflow.Workflow1类型(在第12步中),因此我们的宿主应用程序编译并执行会出错,我们将在下面的一节解决。这里我们就有了一个Windows图形用户界面和宿主应用程序,我们使用它们来承载我们的工作流。谈到工作流,我们不是要创建并执行它吗?其实,这在下面进行讲解。创建一个新的可卸载的工作流1.像前面一章一样,我们又将在我们的项目中创建一个新的顺序工作流库。在Visual Studio中激活WorkflowPersister应

16、用程序,然后点击“文件”菜单,选择“添加”,当子菜单弹出后,选择“新建项目”。从“添加新项目”的对话框中添加一个“顺序工作流库”的项目,项目名称为“PersistedWorkflow”。2.在应用程序解决方案中创建并添加一个新项目后,将呈现该工作流的视图设计器界面。从工具箱中拖拽一个“Code”活动到设计器界面上。在Visual Studio属性面板上设置“Code”活动的“ExecuteCode”属性为PreUnload然后按下回车键。3.然后Visual Studio将自动切换到该工作流的源代码文件中,向刚刚插入的PreUnload方法添加下面的代码:_started = DateTime

17、.Now;System.Diagnostics.Trace.WriteLine(String.Format("* Workflow 0 started: 1",WorkflowInstanceId.ToString(),_started.ToString("MM/dd/yyyy hh:mm:ss.fff");System.Threading.Thread.Sleep(10000); / 10 seconds4.为了计算工作流消耗的时间(下面的步骤中我们将看到,该时间至少在两个Code活动执行的时间之间),我在一个名称为“_started”字段中保存了启动

18、时间。在你的源文件中构造函数的上面添加该字段:private DateTime _started = DateTime.MinValue;5.现在切换到设计视图,添加第二个Code活动。该活动的ExecuteCode属性设置为“PostUnload”,并自动生成该方法。你将看到的设计器界面如下:6.再次切换回工作流的源代码文件中,向PostUnload方法中添加下面必要的代码: DateTime ended = DateTime.Now;TimeSpan duration = ended.Subtract(_started);System.Diagnostics.Trace.WriteLine(String.Format("* Workflow 0 completed: 1, duration: 2",WorkflowInstanceId.ToString(),ended.ToString("MM/dd/yyyy hh:mm:ss.fff"),duration.ToString();7.最后一步是添加一个项目级的引用把该工作流项目引用到我们的主应用程序中,具体步骤可参考前面的章节。备注:现在你或许想运行该程序,但请等等!假如你运行该应用程序,然后点击“Start Workflow”按钮而

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论