如何制作CookieContainer的副本?
鉴于,CookieContainer的实例为不是线程安全的。
Given, instances of CookieContainer are not thread safe.
此类型的任何公共静态(在Visual Basic中为Shared)成员都是线程安全的。不能保证任何实例成员都是线程安全的。
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
因此,事实证明,如果没有多个并发HTTP请求,我不能使用同一容器同步。不幸的是,从MSDN的文档中,尚不清楚如何正确同步它。
So it turns out I cannot use the same container across multiple concurrent HTTP requests without synchronization. Unfortunatelly from the documentation at MSDN it's not clear how one can properly synchronize it.
一种解决方案是为每个请求使用主容器的副本,并且一旦请求被完成后,副本中的cookie可以合并回主容器。
A solution would be using a copy of a master container for each request and once the request is finished the cookies from the copy could be merged back to the master container. Creating a copy and merging can be done in a synchronized manner.
所以问题是:如何制作CookieContainer类的实例的副本?
So the question is : how can I make a copy of an instance of the CookieContainer class?
看看 CookieContainter 类,您会发现在cookie集合中发生更改时会发生并发场景,对吧?
Take a look at the CookieContainter class and you'll see that concurrent scenarios are suppose to occur when there are changes in the cookie collection, right?
您会注意到,CookieContainer的作者负责使用 lock {}
和 SyncRoot
来更改这些更改收藏的内容。部分代码,而且我认为这种方法不适用于并发方案。
You'll notice that the author of CookieContainer took care of using lock {}
and SyncRoot
all around these collection-changing parts of the code, and I don't think that such approach is not addressed to concurrent scenarios.
此外,您还可以注意到,添加的任何 Cookie 实际上是克隆的,因此容器内的cookie和所做的所有操作都不会与cookie容器外部的对象引用混淆。在最糟糕的情况下,我会丢失一些东西,如果使用其他文章中介绍的反射方法(我个人不会考虑),克隆还会为您提供一些提示,告诉您确切的复制内容以及如何进行复制。
Also, you can notice that any added Cookie is literally cloned, so the cookies inside the container and all the operations made will not mess up with object references outside the cookie container. In the worst case of I'm missing something, the clone also gives us a tip of what exactly you have to copy and how you could do it, in case of using the reflection approach described in the other posts (I personally would not consider it a hack, since it fits the requirement and it is managed, legal and safe code :) ).
事实上,所有MSDN文档中提到的都是任何实例。成员不保证是线程安全的。 -这是一种提醒,因为您是对的,所以确实需要小心。然后,使用这种陈述,您基本上可以假设两件事:1)非静态成员根本不安全。 2)有些成员可能是线程安全的,但是没有正确记录。
In fact, the mentions all over MSDN documentation are "Any instance members are not guaranteed to be thread safe." - its a kind of reminder, because you are right, you really need to be careful. Then with such statement you can suppose basically two things: 1) Non-static members are not safe at all. 2) Some members can be thread safe, but they aren't properly documented.