当前位置: 首页 > 编程笔记 >

C# yield在WCF中的错误用法(一)

司浩壤
2023-03-14
本文向大家介绍C# yield在WCF中的错误用法(一),包括了C# yield在WCF中的错误用法(一)的使用技巧和注意事项,需要的朋友参考一下

在定义API的时候,对于一些返回集合对象的方法,很多人喜欢将返回类型定义成IEnumerable<T>,这本没有什么问题。这里要说的是另一个问题:对于返回类型为IEnumerable<T>的方法来说,我们可以使用yield return的方式来输出返回集合的元素。但是如果我们不了解yield 关键字背后的实现机制,很有可能造成很大的问题。

这是一个WCF相关的问题,我想99%的人都有可能会犯这样的错误——即使你对yield了解得非常透彻。闲话少说,我们通过一个简单的实例来说明这个问题。我们定义了如下一个IDemoService接口作为服务契约,唯一的方法GetItems返回一个类型为IEnumerable<string>对象,并且具有唯一字符串参数category。


  [ServiceContract]

  public interface IDemoService

  {

      [OperationContract]

      IEnumerable<string> GetItems(string category);

  }


下面是实现了该契约接口的DemoService的实现:GetItems方法返回一个包含3个字符串的集合,但是在返回之前我们需要对参数实施验证。如果category参数提供的字符串为Null或者是空字符串,抛出一个FaultException异常并提示“Invalid Category”,这样客户端在输入不合法参数的情况下可以得到错误消息。这样的编程方式再正常不过了,不是吗?

public class DemoService : IDemoService

{

    public IEnumerable<string> GetItems(string categoty)

    {

        if (string.IsNullOrEmpty(categoty))

        {

            throw new FaultException("Invalid category");

        }

        yield return "Foo";

        yield return "Bar";

        yield return "Baz";

    }

}


可是正常并不意味着正确,客户端其实根本无法得到服务端提供给它的错误消息,如下所示的是客户端调用服务时指定一个空字符串参数情况下得到的错误。一个CommunicationException异常被抛出来,得到的错误消息为“An error occurred while receiving the HTTP response to http://127.0.0.1:3721/demoservice. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.”

这貌似和我们预期的效果不一样,我们希望的是客户端抛出一个FaultException,并提示“Invalid category”。这实际上就是因为“yield”在作祟,不相信的话可以将定义在DemoService的GetItems方法替换成如下的定义,即直接返回一个string[]对像。


public class DemoService : IDemoService

{

    public IEnumerable<string> GetItems(string categoty)

    {

        if (string.IsNullOrEmpty(categoty))

        {

            throw new FaultException("Invalid category");

        }

        return new string[] { "Foo", "Bar", "Baz" };

    }

}

再次运行我们的程序,这回可以得到我们期望的结果了。

有兴趣的朋友可以思考一下为什么两种貌似等效的方式为何会出现完全不同的结果,具体原因请看[下篇]。

 类似资料:
  • 本文向大家介绍C#中yield return用法分析,包括了C#中yield return用法分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#中yield return用法,并且对比了使用yield return与不使用yield return的情况,以便读者更好的进行理解。具体如下: yield关键字用于遍历循环中,yield return用于返回IEnumerable<T>,y

  • 几天来,我们一直遇到一个WCF通信错误,我不知道是什么导致了这个错误。我最初认为这是一个SSL证书问题,但它不是。我还确保只要在web浏览器上输入URL就可以到达endpoint,并且可以查看。我还确保默认的请求大小不会导致这个问题。我确信这些请求小于默认的30MB。 还有什么东西可以防止这种堆栈跟踪错误? 客户端堆栈跟踪: 由于通信失败,WCFDirector获取失败。 因为表单没有正确加载,所

  • 问题内容: 在一个较大的项目中,我很难获得WCF服务方法来使用JSON参数。因此,我制作了一个较小的测试用例,并产生了相应的行为。如果我调试服务,则可以在服务调用中看到参数值为null。Fiddler确认正在发送JSON,JsonLint确认它有效。 下面的代码带有调试注释。 …及其实施 调用前三个方法中的任何一个都可以正常工作(但没有参数,您会注意到)。使用此客户端代码调用最后一个方法(Tota

  • 在这段代码的第35行使用abs()函数出错。编译器我选择了:c(4.3.2) 查看底部的错误。 prog.cpp:在函数空bfs(std::对)中: 掠夺。cpp:35:错误:重载“abs(int)”的调用不明确 /usr/include/c/4.3/cmath:99:注:候选项为:双std::abs(双)/usr/include/c/4.3/cmath:103:注:浮点std::abs(浮点)

  • 本文向大家介绍wcf WCF中的序列化,包括了wcf WCF中的序列化的使用技巧和注意事项,需要的朋友参考一下 示例 序列化是将对象转换为字节流以存储对象或将其传输到内存,数据库或文件的过程。Microsoft页面序列化 下面的示例演示了WCF中的序列化: [DataContract]属性与类一起使用。在这里,它装饰有Person阶级。 [OperationContract]用于方法。在这里用Ad

  • 本文向大家介绍Python yield的用法实例分析,包括了Python yield的用法实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Python yield的用法。分享给大家供大家参考,具体如下: yield的英文单词意思是生产,刚接触Python的时候感到非常困惑,一直没弄明白yield的用法。 只是粗略的知道yield可以用来为一个函数返回值塞数据,比如下面的例子: 取出

  • 其实,我并不是因为迭代或者生成器或者研究 PHP 手册才认识的 yield,要不是协程,我到现在也不知道 PHP 中还有 yield 这么个鬼东西。人家这个东西是从 PHP 5.5 就开始引入了,官方名称叫做生成器。你要说为什么 5.5 年代的东西,现在才拿出来。我还想问你哟,PHP 5.3 就有了的 namespace 为毛到最近这几年才开始正式投产。 那么,问题来了,这东西到底是有何用? 先来

  • yield()应该做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。 结论:yield()从未导致线程转到等待/睡眠/阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没