【问题标题】:How to know if HttpWebClientProtocol class is Thread Safe?如何知道 HttpWebClientProtocol 类是否是线程安全的?
【发布时间】:2015-12-08 15:12:17
【问题描述】:

我阅读了this 问题,但答案和讨论让我自己感到困惑。

所以我决定检查一下,但我该怎么做呢?如何创建一个测试来证明HttpWebClientProtocol class 是否为Thread Safe

我已经做了以下测试:

  1. 创建一个HttpWebClientProtocol 来调用一个WS。
  2. 我自己创建了 WS,里面只有一个 Thread.Sleep(30000)
  3. 所以我创建了两个独立的threads 来同时调用这个HttpWebClientProtocol
  4. 结果是:threads 都调用了 WS 没有问题。 (一个thread 不需要等待第一个通话结束)

通过这个测试,我是否证明了对象 IS Thread Safe 和另一个问题的“正确”答案是错误的??

【问题讨论】:

  • 在这里理解有什么问题? “不。它不是线程安全的。客户端必须处于打开状态才能启用调用。一个简单的场景是一个线程执行 client.Close() 而另一个线程尝试调用方法将失败。”简单地说,不,不是。如果你想测试它,你应该阅读多线程以及如何使用它。但你也应该知道,这样的测试不是很可靠
  • 你读过MSDN documentation中的线程安全吗?
  • 第二个@mikus 说的。即使某些东西不是线程安全的,您也可以运行数十个测试,并且不能保证它会出现任何问题。多线程是一件棘手的事情,您可能会在测试中得到不一致的行为。

标签: c#


【解决方案1】:

嗯...我有一个更好的测试给你。

HttpWebClientProtocol Class

直接来自 MSDN。这是他们对线程安全的看法的副本/意大利面:

线程安全

对于每个 XML Web 服务方法调用,此类的属性都被复制到 WebRequest 对象的新实例中。虽然您可以同时从不同线程调用同一个 WebClientProtocol 实例上的 XML Web 服务方法,但不会进行同步以确保将一致的属性快照传输到 WebRequest 对象。因此,如果您需要修改属性并从不同线程进行并发方法调用,您应该使用不同的 XML Web 服务代理实例或提供您自己的同步。

关于线程安全

这不仅仅是“可用”。但这是为了确保受一个线程影响的数据/状态不会影响另一个线程的正确执行。

如果它们共享数据结构并且这些结构在线程之间共享,则它们不是线程安全的。这个问题可能不是很明显,但是在多线程系统中大量使用该类的系统上,您可能会发现一些您将无法在开发环境中重现的错误/异常/奇怪行为,并且“只发生在生产中”。

我的朋友,不是线程安全的。

关于 HttpWebClientProtocol 以及为什么它不是线程安全的

虽然文档清楚地说明了能够重用 HttpWebClientProtocol,但重要的是要知道对象本身的所有属性都不会被持久化到在另一个线程上创建的其他请求。

这意味着如果您有 2 个线程在使用 Credentials 属性,您最终可能会收到一些具有不同凭据的请求。这在具有模拟的 Web 应用程序中会很糟糕,因为请求可以使用不同的凭据完成,而您最终可能会得到其他人的数据。

但是,如果您只需要设置一次初始属性,那么可以。您可以重复使用该实例。

【讨论】:

  • 谢谢你的回答,哦,所以这个MSDN的话题正是我自己得出的结论,真的是Thread Safe,但如果我不需要为每次调用更改对象的属性;
  • 它就像 MSDN 上提到的那样“线程安全”。不再。不少于。没有辩论。没有争论。就是这样。
  • 是但不是。哈哈哈
  • 不是。您可以对其进行多线程调用,但如果您开始更改属性(如EnableDecompression 等...),那么它们可能会影响其他线程,因为您基本上是在同一个实例上操作。这就是“非线程安全”的确切定义。一个线程中的一个更改会影响另一个线程。如果您不必多次使用属性,那么可以,您可以在多线程场景中重用对象。但它不是线程安全的。
  • 好答案,现在我明白了。已接受答案:)
猜你喜欢
  • 1970-01-01
  • 2013-02-17
  • 2012-08-15
  • 1970-01-01
  • 2012-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-17
相关资源
最近更新 更多