如何制作CookieContainer的副本?

Tri*_*Gao 3 .net c# cookies

鉴于,CookieContainer的实例不是线程安全的.

此类型的任何公共静态(在Visual Basic中为Shared)成员都是线程安全的.任何实例成员都不保证是线程安全的.

所以事实证明,如果没有同步,我不能在多个并发HTTP请求中使用相同的容器.不幸的是,MSDN的文档不清楚如何正确地同步它.

解决方案是为每个请求使用主容器的副本,一旦请求完成,副本中的cookie可以合并回主容器.创建副本和合并可以以同步方式完成.

所以问题是:如何复制CookieContainer类的实例?

Ala*_*lan 8

CookieContainer类是Serializable.既然你说你需要序列化它,为什么不只是使用BinaryFormatter将它序列化为MemorySteam然后反序列化它来制作副本?

我知道这太简单了,所以请忽略它是否有用.

private CookieContainer CopyContainer(CookieContainer container)
{
    using(MemoryStream stream = new MemoryStream())
    {
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize(stream, container);
        stream.Seek(0, SeekOrigin.Begin);
        return (CookieContainer)formatter.Deserialize(stream);
    }
}
Run Code Online (Sandbox Code Playgroud)


nat*_*nho 5

看一看CookieContainter类,您会发现当 cookie 集合发生变化时会发生并发场景,对吗?

您会注意到 CookieContainer 的作者负责使用lock {}SyncRoot处理代码中这些更改集合的部分,我认为这种方法不是针对并发场景的。

此外,您可以注意到任何添加的Cookie都是按字面意思克隆的,因此容器内的 cookie 和所做的所有操作都不会与 cookie 容器外的对象引用混淆。在最坏的情况下,我遗漏了一些东西,如果使用其他帖子中描述的反射方法(我个人不会考虑这是一个 hack,因为它符合要求并且它是受管理的、合法和安全的代码 :))。

事实上,整个 MSDN 文档都提到“不保证任何实例成员都是线程安全的”。- 这是一种提醒,因为你是对的,你真的需要小心。然后通过这样的声明,您基本上可以假设两件事:1)非静态成员根本不安全。2) 一些成员可以是线程安全的,但它们没有正确记录。