问题
I am doing a kind of WebCrawler and I need to persist the Cookies state between requests.
I download all pages async creating new HttpWebRequest instances, but setting the same CookieContainer. The pages can write and read cookies.
Can I do it safely? There is any alternative that isn´t subclass the CookieContainer and put locks at all method?
The MSDN says that this class isn´t thread safe, but in practice, can I do it?
回答1:
According to the documentation:
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
So, you should ensure proper locking if you want to share the same instance between multiple threads. But since the members of the CookieContainer
class are actually not manipulated by your code, but implicitly from the different HttpWebRequest instances that you created it could not be easy to synchronize properly, other than of course locking on your requests which of course kind of defeats the purpose and the level of parallelism that I suppose you are trying to achieve here.
Whether in practice you will get problems is another topic. The thing is that the documentation (and thus the author) doesn't provide you any guarantees.
回答2:
Actually, if you look at the source code of CookieContainer
here. It appears that it is thread-safe despite the documentation.
A nice answer that explains it.
https://stackoverflow.com/a/18370195/5088793
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.
So, as a general rule
When you see the standard Any instance members are not guaranteed to be thread safe.
documentation, don't just stop there and implement a lock yourself. Use reflection or referencesource.microsoft.com (for .NET classes) to find out whether they are thread safe or not.
来源:https://stackoverflow.com/questions/9911744/is-it-safe-to-use-the-same-cookiecontainer-across-multiple-httpwebrequests