|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
WebClient OpenRead & Threading IssueI have been working on a windows service that with retrieve XML files from remote sites at a predetermined frequency. I am using the WebClient class to retrieve any XML files located on web servers. When I execute a call to each remote source in linear progression I encounter no problems. If I execute the service with only one remote source identified I encounter no problems. It is only when I try to execute the service with multiple sources identified that I encounter the problem. After the threading was incorporated I started receiving the following error: "Non-negative number required. Parameter name: byteCount" "byteCount" is not a variable that I have declared and after a combination of online research and a thorough application review I have determined that this variable is part of the framework itself. I have tried implementing synchronization using the Mutex class with no success. I have also tried the various solutions (delegation, etc.) identified in the newsgroups posted in response to similar issues to the one I am encountering with no avail. Could someone please provide me with some guidance on this issue? I have spent more time than I would like on this issue and would like to get past it before it costs me my sanity. I can provide a working sample of the issue if required just let me know. Thanks in advance. JS. JS wrote:
Show quote > All, Note that this class isn't thread-safe. > > I have been working on a windows service that with retrieve XML files > from remote sites at a predetermined frequency. I am using the > WebClient class to retrieve any XML files located on web servers. > When I execute a call to each remote source in linear progression I > encounter no problems. If I execute the service with only one remote > source identified I encounter no problems. It is only when I try to > execute the service with multiple sources identified that I encounter > the problem. > > After the threading was incorporated I started receiving the following > error: > "Non-negative number required. > Parameter name: byteCount" > > "byteCount" is not a variable that I have declared and after a > combination of online research and a thorough application review I > have determined that this variable is part of the framework itself. > > I have tried implementing synchronization using the Mutex class with > no success. I have also tried the various solutions (delegation, > etc.) identified in the newsgroups posted in response to similar > issues to the one I am encountering with no avail. > > Could someone please provide me with some guidance on this issue? I > have spent more time than I would like on this issue and would like to > get past it before it costs me my sanity. I can provide a working > sample of the issue if required just let me know. Are you reusing the same WebClient instance across threads? It's much easier and more scalable to use one WebClient instance per thread. Cheers, > Note that this class isn't thread-safe. Hi Joerg,> > Are you reusing the same WebClient instance across threads? > > It's much easier and more scalable to use one WebClient instance per > thread. > Thanks for the response. In reply to your question I am not using one WebClient instance across threads. Originally I was but I corrected that prior to receiving the error previously identified. Presently I am using one instance per thread. The class that the WebClient is within is self-contained and is instantiated uniquely by the calling class. It is this calling class that is created uniquely for each thread. i.e. [delegate class] ..... thr = new Thread(new ThreadStart(AddressOf GenService.GetSourceInfo)) [inside GenService class] .... dim oRemote as new Remote() [inside Remote class] private shared oWC as new WebClient .... private function GetData() as boolean .... dim sr as streamreader .... sr = new StreamReader(oWC.OpenRead(URL)) .... end function That is the line where it fails. Does that make sense? I hope the clarification helps. Regards, J.
Show quote
"JS" <gq_s2***@hotmail.com> wrote in message As far as I can see, WebClient is shared, which I guess is VB equivalent of news:1132632427.153033.10960@g43g2000cwa.googlegroups.com... .... > > [delegate class] > .... > thr = new Thread(new ThreadStart(AddressOf GenService.GetSourceInfo)) > > [inside GenService class] > ... > dim oRemote as new Remote() > > [inside Remote class] > > private shared oWC as new WebClient > ... .... static in C#. That means that all instances of Remote class will use same WebClient. Can you test with 'shared' keyword removed? Regards, Goran Hi Goran,
Yes, that is correct. "Shared' is the VB equivalent to static in C#. I have declared this variable as such based on the .NET 1.1 SDK stating that the only threadsafe members of this type are the public static variables. However, I will make the change and see what happens. [a short while later] I have just tried changing how the WebClient reference is instantiated to not use the "Shared" keyword and the error still occurs. I have tried declaring the variable as both public and private to no avail. Would you have any other suggestions? Regards, Jeff. JS wrote:
Show quote > Hi Goran, Jeff,> > Yes, that is correct. "Shared' is the VB equivalent to static in C#. > I have declared this variable as such based on the .NET 1.1 SDK > stating that the only threadsafe members of this type are the public > static variables. However, I will make the change and see what > happens. > > [a short while later] > I have just tried changing how the WebClient reference is instantiated > to not use the "Shared" keyword and the error still occurs. I have > tried declaring the variable as both public and private to no avail. > > Would you have any other suggestions? *don't* use a WebClient object that is a class member (even if it is non-static) when multiple threads may execute methods of a single instance of your GenService class. The easiest and safest thing to do is to create a WebClient object as a local variable in your GetData() method and not to use instance fields. Thus, each thread will have its own WebClient instance, and there will be no threading issues. Cheers, Hi Goran/Joerg,
First and foremost thank you both for taking the time to patiently explain what was going on and offer tips. About all I have to say is.... $@#%$#$ This exercise will teach me to RTFM a little more closely. I realize now when I read the information regarding Thread Safety in the SDK for the WebClient class that I "skimmed" it rather than "read" it and did not note the obvious....that the comments relate to the MEMBERS of the class and not the class itself. Thank you both again for the assistance. Regards, Jeff. JS wrote:
Show quote > > Note that this class isn't thread-safe. Well, there's nothing much to say after Goran's post. You share a> > > > Are you reusing the same WebClient instance across threads? > > > > It's much easier and more scalable to use one WebClient instance per > > thread. > > > > Hi Joerg, > > Thanks for the response. In reply to your question I am not using one > WebClient instance across threads. Originally I was but I corrected > that prior to receiving the error previously identified. Presently I > am using one instance per thread. > > The class that the WebClient is within is self-contained and is > instantiated uniquely by the calling class. It is this calling class > that is created uniquely for each thread. > > i.e. > > [delegate class] > .... > thr = new Thread(new ThreadStart(AddressOf GenService.GetSourceInfo)) > > [inside GenService class] > ... > dim oRemote as new Remote() > > [inside Remote class] > > private shared oWC as new WebClient > ... > private function GetData() as boolean > ... > dim sr as streamreader > ... > sr = new StreamReader(oWC.OpenRead(URL)) > ... > end function > > That is the line where it fails. > > Does that make sense? I hope the clarification helps. single instance between threads. Use a WebClient instance per thread. Cheers, |
|||||||||||||||||||||||