zoukankan      html  css  js  c++  java
  • Beginning WF 4.0——翻译(第六章异常处理)

    在这一章,你将添加逻辑去验证订单项是否有存货。为了去完成它,你需要重复用同样的方式验证每一个订单项,如果有一项没有存货,你将抛出一个异常,这个异常可以被你的工作流捕获。

    重新利用Chapter5项目

    打开Visual Studio 2010 创建一个新的项目,选择Blank Solution模板,如图Figure6-1所示。输入解决方案名为Chapter06

    复制Chapter05目录下的OrderProcess文件夹到Chapter06的目录下。在Solution Explorer中,右击Chapter06解决方案,选择Add>Existing ProjectAdd Existing Project对话框会出现。选择Chapter06\OrderProcess下的OrderProcess.csproj文件。(这跟上一章的做法是一样的。)

    添加检验存货活动

    现在你将要添加逻辑去验证是否有充足的存货给订单了。

    TryCatch活动

    打开OrderWF.xaml文件的设计视图。拖拉一个TryCatch活动到“Handling Charges”活动的下面。修改DisplayNameCheck Stock,点击活动右上角的展开按钮。设计视图如图Figure6-2所示。

    TryCatch活动有三个节点。在Try节点中,你可以放置一系列可能产生异常的活动。在Catches节点中,你可以定义一个或多个Catch对象。每一Catch对象处理一个特定的异常。Finally节点是可选的。你可以放置一系列活动到这里,这里的活动是在Try活动(和任何被异常引发的Catch对象)执行完之后执行的。

    定义一个异常

    你将定义一个异常,这个异常是当没有存货时抛出的。打开Order.cs文件,添加下面的代码去定义OutOfStockException类。

        //----------------------------------------

        //define the exception to be thrown if an item

        //is out of stock

        //----------------------------------------

        public class OutOfStockException : Exception

        {

            public OutOfStockException()

                : base()

            { }

     

            public OutOfStockException(string message)

                : base(message)

            { }

        }

    这应该添加在Order类定义之后,在OrderProcess命名空间中。完整的Order.cs如下所示:

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

     

    namespace OrderProcess

    {

        public class OrderItem

        {

            public int OrderItemID { get; set; }

            public int Quantity { get; set; }

            public string ItemCode { get; set; }

            public string Description { get; set; }

        }

     

        public class Order

        {

            public Order()

            {

                Items = new List<OrderItem>();

            }

     

            public int OrderID { get; set; }

            public string Description { get; set; }

            public decimal TotalWeight { get; set; }

            public string ShippingMethod { get; set; }

     

            public List<OrderItem> Items { get; set; }

        }

     

        //----------------------------------------

        //define the exception to be thrown if an item

        //is out of stock

        //----------------------------------------

        public class OutOfStockException : Exception

        {

            public OutOfStockException()

                : base()

            { }

     

            public OutOfStockException(string message)

                : base(message)

            { }

        }

    }

    ForEach活动

    拖放一个ForEach活动到Try节点中,设置DisplayNameCheck Each Item。点击展开按钮,在Expression中输入以下代码:

    OrderInfo.Items

    这定义了循环访问订单项中的每一项。(ForEach活动的详细信息请参考第五章。)在属性窗口中,对于TypeArgument属性,选在Browse for Types,然后选择OrderProcess引用下的OrderItem类。(跟第五章一样)。

    If活动

    拖拉一个If活动到Body节点,展开活动,设置DisplayNameIf Out of Stock。如图Figure6-3所示。

    Condition属性中输入下面代码:

    Item.ItemCode = “12346”

    提示:在真正的程序开发中,你会从数据库中取出数据,然后验证这些数据是否没有存货。在这个示例中,判断是否没有存货是硬编码的。

    Throw活动

    拖放一个Throw活动到Then节点。在属性窗口,它只有两个属性:DisplayNameException。对于Exception属性,输入下面代码:

    New OrderProcess.OutOfStockException”Item Code: ” + item.ItemCode

    这创建了一个OutOfStockException对象,指定了是哪个订单项是没有存货的信息。“If Out of Stock”活动应该如图Figure6-4所示。

    Catch活动

    Check Stock”活动应该如图Figure6-5所示。

    点击Add new catch链接。将会出现一个下拉列表,选择Browse for Types,选择OrderProcess引用下的OutOfStockException,如图Figure6-6所示。

    图形应该如图Figure6-7所示。

    你将会捕获循环的异常,你应该定义可以执行处理这个异常的活动。对于这个项目,你将输出一行信息去指出是哪一项是没有存货的。拖放一个WriteLine活动到Catches节点中,Text属性为:

     

    “Item is out of stock - ” + exception.Message

    这行代码从异常中获取信息,信息包含了没有存货的订单项号。收缩“Check Stock”活动然后展开它。“Check Stock”的最终如图Figure6-8所示。

    运行程序

    点击F5,结果如下所示:

    异常

    选择在哪里摆放异常处理时非常重要的。例如你可以把整个工作流摆放到一个TryCatch活动的Try节点中,虽然这是一个简单的方式去捕获所有的异常。但是,这可能没有让你真正的去处理这些异常。让我解析一下。

    当一个异常被抛出,如果他不是被父活动捕获的,父活动将会流产,而剩下的子活动将会不会被执行。在这个项目中,例如,异常时被If活动的Then分支抛出的。TryCatchForEach活动之外。因为异常没有更早的捕获,当异常到达ForEach活动时,ForEach活动将会停止循环。这意味着一旦异常抛出,工作流将会停止检验其他的订单项。这就是我想说的。

    下面的伪代码展示了它是怎么工作的:

    Sequence

    {

    CheckStock (Try)

    {

    Check Each Item (ForEach)

    {

    If Out of Stock (If)

    {

    Throw Exception (Then)

    }

    }

    }

    Catch

    {

     }

    Remaining Activities

    }

     

    当一个异常抛出,程序会直接去到Catch序列,然后工作流会在Catch这里继续执行下去。这种设计,你可以用来处理费用异常,然而,如果你想继续检验剩下的订单项,你需要把TryCatch活动放到If活动的外面,这会在异常到达ForEach活动之前被处理掉。如下伪代码所示:

    Sequence

    {

    Check Each Item (ForEach)

    {

    (Try)

    {

    If Out of Stock (If)

    {

    Throw Exception (Then)

    }

    }

    Catch

    {

    }

    }

    }

     

    因为Catch序列在ForEach活动之内,一旦Catch被执行,工作流会接着去处理下一个订单项,如果,你想在异常发生的时候,整个工程要停止,你可以把TryCatch活动放到整个工作流的最顶层,如下所示:

     

    (Try)

    {

    Sequence

    {

    Check Each Item

    {

    If Out of Stock

    {

    Throw Exception

    }

    }

    Remaining Activities

    }

    }

    Catch

    {

    }

     

    因为Catch序列在最外面,在Catch执行完之后,工作流也会完成。

     

    第六章源码下载

  • 相关阅读:
    【codeforces 29B】Traffic Lights
    【codeforces 131E】Yet Another Task with Queens
    Java数据结构与算法(8)
    fdisk一键操作分区-无需脚本
    【codeforces 46C】Hamsters and Tigers
    【codeforces 417D】Cunning Gena
    【codeforces 95C】Volleyball
    【codeforces 229C】Triangles
    【codeforces 234F】Fence
    【codeforces 235B】Let's Play Osu!
  • 原文地址:https://www.cnblogs.com/kukafeiso/p/1791776.html
Copyright © 2011-2022 走看看